Squashed 'third_party/lksctp-tools/' content from commit 200eca7f1
Change-Id: I8f7575513f114b205178cac5c6b3706f3d725cb5
git-subtree-dir: third_party/lksctp-tools
git-subtree-split: 200eca7f1419b1ae53958b51e8551f7e7f6cd467
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..ba219a6
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,3 @@
+We don't use pull requests anymore. Please follow Linux netdev community patch
+posting standard instead. Post your patches to linux-sctp@vger.kernel.org and
+they will be very welcomed. Thanks!
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e92e8f8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+aclocal.m4
+config.guess
+config.log
+config.status
+config.sub
+configure
+Makefile.in
+Makefile
+config.h
+config.h.in
+libsctp.pc
+libtool
+lksctp-tools.spec
+stamp-h1
+*.deps/
+*.libs/
+autom4te.cache/
+*.la
+*.lo
+*.o
+tags
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f1b2b49
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,106 @@
+language: c
+addons:
+ apt:
+ packages:
+ - libelf-dev
+script:
+ - ./.travis/linux-build.sh
+env:
+ global:
+ - KERNEL=4.17
+ matrix:
+ - KERNEL=""
+compiler:
+ - gcc
+ - clang
+
+matrix:
+ include:
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libelf-dev
+ - g++-4.9
+ env:
+ - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
+
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libelf-dev
+ - g++-5
+ env:
+ - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
+
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libelf-dev
+ - g++-6
+ env:
+ - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
+
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - libelf-dev
+ - g++-7
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+
+ # works on Trusty
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-trusty-3.9
+ packages:
+ - libelf-dev
+ - clang-3.9
+ env:
+ - MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
+
+ # works on Trusty
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-trusty-4.0
+ packages:
+ - libelf-dev
+ - clang-4.0
+ env:
+ - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
+
+ # works on Trusty
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-trusty-5.0
+ packages:
+ - libelf-dev
+ - clang-5.0
+ env:
+ - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
+before_install:
+ - eval "${MATRIX_EVAL}"
+ - $CC --version
+
+notifications:
+ email:
+ on_success: change
+ on_failure: change
+ recipients: linux-sctp@vger.kernel.org
diff --git a/.travis/linux-build.sh b/.travis/linux-build.sh
new file mode 100755
index 0000000..746f172
--- /dev/null
+++ b/.travis/linux-build.sh
@@ -0,0 +1,86 @@
+#!/bin/bash -ex
+
+VERS="master v4.17 v4.16 v4.13 v4.12 v4.11 v4.10"
+
+nproc=$(/usr/bin/getconf _NPROCESSORS_ONLN)
+basedir=$(pwd)
+
+function cleanup()
+{
+ cd "$basedir"
+ [ ! -d linux ] || rm -rf linux
+ [ ! -d "linux-$KERNEL" ] || rm -rf "linux-$KERNEL"
+ make distclean || :
+}
+
+function clone_kernel()
+{
+ git clone https://github.com/torvalds/linux
+}
+
+function download_kernel()
+{
+ VER="$1"
+ URL="https://www.kernel.org/pub/linux/kernel/v4.x/linux-$VER.tar.xz"
+ wget "$URL"
+ tar xf "linux-$VER.tar.xz"
+}
+
+function __prep_kernel()
+{
+ make mrproper
+ make allmodconfig
+ make -j $nproc modules_prepare
+ make -j $nproc headers_install
+ KERNEL_HEADERS=$(pwd)/usr/include
+ popd
+}
+
+function git_prep_kernel()
+{
+ VER="$1"
+
+ pushd "linux"
+ git checkout "$VER"
+ __prep_kernel
+}
+
+function download_prep_kernel()
+{
+ VER="$1"
+
+ pushd "linux-$VER"
+ __prep_kernel
+}
+
+function build_lksctp()
+{
+ make distclean || :
+ ./bootstrap
+
+ #CFLAGS="-Werror"
+ if [ -n "$KERNEL_HEADERS" ]; then
+ CFLAGS="$CFLAGS -I$KERNEL_HEADERS"
+ fi
+ export CFLAGS
+ ./configure
+
+ make -j $nproc
+
+ #make -j $nproc distcheck
+
+}
+
+trap cleanup EXIT
+if [ -z "$KERNEL" ]; then
+ clone_kernel
+
+ for ver in $VERS; do
+ git_prep_kernel "$ver"
+ build_lksctp
+ done
+else
+ download_kernel "$KERNEL"
+ download_prep_kernel "$KERNEL"
+ build_lksctp
+fi
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..01c25c0
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,36 @@
+The initial developer and founder of the project:
+-------------------------------------------------
+La Monte H.P. Yarroll <piggy@acm.org>
+
+Current Maintainer:
+-------------------
+Vlad Yasevich <vyasevic@redhat.com>
+Daniel Borkmann <dborkman@redhat.com>
+
+Previous Maintainers:
+--------------------
+Sridhar Samudrala <sri@us.ibm.com>
+Jon Grimm <jgrimm@us.ibm.com>
+
+Contributors:
+-------------
+Karl Knutson <karl@athena.chicago.il.us>
+Xingang Guo <xingang.guo@intel.com>
+Daisy Chang <daisyc@us.ibm.com>
+Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+Hui Huang <hui.huang@nokia.com>
+Dajiang Zhang <dajiang.ahang@nolia.com>
+Ryan Layer <rmlayer@us.ibm.com>
+Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com>
+Frank Filz <ffilz@us.ibm.com>
+Ivan Skytte Jorgensen <isj-sctp@i1.dk>
+Neil Horman <nhorman@tuxdriver.com>
+Michael Biebl <biebl@debian.org>
+Wei Yongjun <yjwei@cn.fujitsu.com>
+Sam Miller <samjmill@us.ibm.com>
+Andrei Pelinescu-Onciul <andrei@iptel.org>
+Michele Baldessari <michele@acksyn.org>
+Michael Tuexen <tuexen@fh-muenster.de>
+Fan Du <fan.du@windriver.com>
+
+Are you missing? drop us a line!
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..dc63aac
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/COPYING.lib b/COPYING.lib
new file mode 100644
index 0000000..7d31de0
--- /dev/null
+++ b/COPYING.lib
@@ -0,0 +1,456 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..3f723aa
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,917 @@
+Version 1.0.18 of the Developers' Release of the SCTP
+Linux Kernel Implementation is available from
+
+ http://www.kernel.org
+
+lksctp-1.0.18: Mon Aug 13 16:19 EDT 2016
+T:APP Various test tools fixes
+T:LIB Added support for sctp_peeloff_flags function
+T:LIB Added macro definitions indicating which kernel
+ features were detected during build.
+T:LIB Initial batch of fixes for coverity scan issues
+T:NA Initial integration with Travis and Coverity Scan
+T:BUILD Updated rfc listings so now 'make distcheck' works
+
+lksctp-1.0.17: Mon May 9 16:19 EDT 2016
+T:APP Various sctp_test fixes
+T:TEST also expect EACCES when accept on an established socket
+T:LIB Make use of 'extern "C"'
+T:NA Make use .git_ignore
+T:NA Removed sysctl listing from man page
+T:BUILD Added support for pkg-config
+T:BUILD Allow not building tests
+
+lksctp-1.0.16: Tue Feb 18 11:01 EDT 2014
+T:APP Code cleanups
+T:APP Various sctp_status fixes
+T:TEST Avoid using file descriptor 0 to get ENOTSOCK
+T:TEST Various fixes
+T:LIB Fix build for prefixed architectures
+
+lksctp-1.0.15: Sun May 12 11:01 EDT 2013
+T:BUILD Allow build with no AM_SILENT_RULES support
+T:APP Fix sctp_status
+T:APP Fix quoted command line arguments
+
+lksctp-1.0.14: Wed Apr 05 11:54 EDT 2013
+T:BUILD Modernize and fix autotool's build system
+T:TEST Fix threading test
+T:TEST Zero out flags in sendrecvmsg test
+T:HDR Sync header with the kernel
+
+lksctp-1.0.13: Wed Jan 23 12:13 EDT 2013
+T:BUILD Use silent rules
+T:BUILD Fix build warnings all over the place
+T:APP Fix memory leak in sctp_xconnect
+T:TEST Fix deprecated values in test cases
+
+lksctp-1.0.12: Tue Jan 08 10:45 EDT 2013
+T:API Add needed definitions for DTLS/SCTP.
+T:API Fix data corruption in sctp_send
+T:API Implement private SCTP_GET_ASSOC_STATS option to fetch addition
+ association data.
+T:TEST Add more options to conformace test tool.
+T:APP Add HEARTBEAT command to sctp_darn
+T:API Obsolete interefaces have been removed
+T:API Suport for SCTP_SACK_IMMEDIATELY options
+T:API Support for non-blocking sctp-connectx
+
+lksctp-2.6.28-1.0.11: Wed Oct 21 16:53:41 EDT 2009
+T:BUILD fix parallel build warning
+T:BUILD fix make distcheck for lksctp-tools
+T:BUILD fix compiler warnings in the libraray, apps and tests
+T:API Update the sctp.h header to match the kernel.
+
+lksctp-2.6.28-1.0.10: Fri Mar 27 11:15:25 EDT 2009
+T:TEST Split the kernel frame test framework from lksctp-tools. The
+ framework is very sensitive to all kernel changes, not just ones
+ related to SCTP. As such, it has been a gating fractor to the
+ releases of the new tools.
+T:APP New tool sctp_status to be used with SCTP conformance tests.
+ http://networktest.sourceforge.net/
+T:APP Add -T option to sctp_test
+T:APP Fix the -e option to sctp_darn
+T:LIB Fix building of static libraries.
+T:LIB Fix compile warning in addrs.c
+T:APP Update the application useage of sctp_connectx
+T:TEST Update the sctp_connectx() functional tests.
+T:API Update to the sctp_connectx(). Now takes additional argument.
+T:API Let sctp_recvmsg() honor passed in MSG_ flags
+K: See kernel change log for details. We'll track only tools
+ changes here from now on.
+
+lksctp-2.6.26-1.0.9: Sun Jul 13 14:51:29 PDT 2008
+T:Patch Make frame tests work with 2.6.26 kernel.
+T:Patch Implement and export SCTP-AUTH API extensions based on
+ sctpsocket-16 draft
+T:NA Process withsctp.in at build time
+K:Patch Add documentation for sctp sysctl variable
+K:NA Mark the tsn as received after all allocations finish
+K:NA Make sure N * sizeof(union sctp_addr) does not overflow.
+K:NA Correclty set changeover_active for SFR-CACC
+K:NA Correctly cleanup procfs entries upon failure.
+K:NA Fix ECN markings for IPv6
+K:NA Flush the queue only once during fast retransmit.
+K:NA Start T3-RTX timer when fast retransmitting lowest TSN
+K:NA Correctly implement Fast Recovery cwnd manipulations.
+K:NA Move sctp_v4_dst_saddr out of loop
+K:NA retran_path update bug fix
+K:NA Fix NULL dereference of asoc.
+K:NA Fix use of uninitialized pointer
+K:NA Add address type check while process paramaters of ASCONF chunk
+K:NA Do not enable peer IPv6 address support on PF_INET socket
+K:NA Initialize partial_bytes_acked to 0, when all of the data is acked
+K:NA IPv4 vs IPv6 addresses mess in sctp_inet[6]addr_event.
+K:NA Fix compiler warning about const qualifiers
+K:NA Fix protocol violation when receiving an error lenght INIT-ACK
+K:NA Add check for hmac_algo parameter in sctp_verify_param()
+K:Patch New sctp mailing list
+K:NA Remove an unused parameter from sctp_cmd_hb_timer_update
+K:Patch "list_for_each()" -> "list_for_each_entry()" where appropriate.
+K:NA Correct /proc/net/assocs formatting error
+K:Patch Use snmp_mib_{init,free}().
+K:Patch Remove useless assignment from __sctp_rcv_lookup_endpoint
+K:NA fix wrong debug counting of bind_bucket
+K:NA fix wrong debug counting of datamsg
+K:Patch Replace socket with sock for SCTP control socket.
+K:Patch Use inet_ctl_sock_create for control socket creation.
+K:Patch Remove sctp_add_cmd_sf wrapper bloat
+K:Patch Remove redundant wrapper functions.
+K:Patch Replace char msg[] with static const char[]
+K:NA Fix a race between module load and protosw access
+K:NA fix misannotated __sctp_rcv_asconf_lookup()
+K:NA Fix local_addr deletions during list traversals.
+K:Patch Bring MAX_BURST socket option into ietf API extension compliance
+K:NA Fix chunk parameter processing bug
+K:Patch Kill unused static inline sctp_sysctl_jiffies_ms
+K:Patch extend exported data in /proc/net/sctp/assoc
+K:Patch Use proc_create to setup de->proc_fops.
+K:Patch Update AUTH structures to match declarations in draft-16.
+K:NA Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option
+K:Patch Clean up naming conventions of sctp protocol/address family
+ registration
+K:NA Correctly set the length of sctp_assoc_change notification
+K:NA Pick up an orphaned sctp_sockets_allocated counter.
+K:Patch Convert sctp_dbg_objcnt to seq files.
+K:Patch Use snmp_fold_field instead of a homebrew analogue.
+K:NA Make sure the chunk is off the transmitted list prior to freeing.
+K:NA Fix kernel panic while received ASCONF chunk with bad serial
+ number
+K:NA Set ports in every address returned by sctp_getladdrs()
+K:NA Correctly reap SSNs when processing FORWARD_TSN chunk
+K:NA Fix kernel panic while received AUTH chunk with BAD shared key
+ identifier
+K:NA Fix kernel panic while received AUTH chunk while enabled auth
+K:Patch Kill silly inlines in ulpqueue.c
+K:NA Do not increase rwnd when reading partial notification.
+K:Patch Stop claiming that this is a "reference implementation"
+K:NA Fix miss of report unrecognized HMAC Algorithm parameter
+K:NA Correctly initialize error when parameter validation failed.
+K:Patch Follow Add-IP security consideratiosn wrt INIT/INIT-ACK
+K:Patch Implement ADD-IP special case processing for ABORT chunk
+K:Patch Change use_as_src into a full address state
+K:Patch Update ASCONF processing to conform to spec.
+K:Patch ADD-IP updates the states where ASCONFs can be sent
+K:Patch Update association lookup to look at ASCONF chunks as well
+K:Patch Add the handling of "Set Primary IP Address" parameter to INIT
+K:Patch Handle the wildcard ADD-IP Address parameter
+K:Patch Discard unauthenticated ASCONF and ASCONF ACK chunks
+K:Patch Use crc32c library for checksum calculations.
+K:Patch Use ipv4_is_<type>
+
+lksctp-2.6.24-1.0.8: Fri Feb 01 14:55:00 EST 2008
+K:NA Add back the code that accounted for FORWARD_TSN parameter in
+ INIT.
+K:NA Correctly handle AUTH parameters in unexpected INIT
+K:NA Fix the name of the authentication event.
+K:NA Spelling fixes
+K:NA Flush fragment queue when exiting partial delivery.
+K:NA Fix the bind_addr info during migration.
+K:NA Add bind hash locking to the migrate code
+K:NA Fix build issues with SCTP AUTH.
+K:NA Fix chunk acceptance when no authenticated chunks were listed.
+K:NA Fix the supported extensions paramter
+K:NA Fix SCTP-AUTH to correctly add HMACS paramter.
+K:NA Fix the number of HB transmissions.
+K:NA Add missing "space"
+K:NA Always flush the queue when uncorcking.
+K:NA Clean-up some defines for regressions tests.
+K:NA Fix PR-SCTP to deliver all the accumulated ordered chunks
+K:NA Make sctp_verify_param return multiple indications.
+K:NA Convert custom hash lists to use hlist.
+K:NA Use hashed lookup when looking for an association.
+K:NA Fix a potential race between timers and receive path.
+K:NA Allow ADD_IP to work with AUTH for backward compatibility.
+K:NA Correctly disable ADD-IP when AUTH is not supported.
+K:NA Update RCU handling during the ADD-IP case
+K:NA Fix difference cases of retransmit.
+K:NA Fix to process bundled ASCONF chunk correctly
+K:NA Fix bad formatted comment in outqueue.c
+Patch Use the {DEFINE|REF}_PROTO_INUSE infrastructure
+K:NA SCTP endianness annotations regression
+K:NA net/sctp/auth.c: make 3 functions static
+K:NA #if 0 sctp_update_copy_cksum()
+K:NA Consolidate sctp_ulpq_renege_xxx functions
+Patch port randomization
+Patch Tie ADD-IP and AUTH functionality as required by spec.
+Patch API updates to suport SCTP-AUTH extensions.
+Patch Implement the receive and verification of AUTH chunk
+Patch Enable the sending of the AUTH chunk.
+Patch Implement SCTP-AUTH parameter processing
+Patch Implement SCTP-AUTH initializations.
+Patch Implement SCTP-AUTH internals
+Patch protocol definitions for SCTP-AUTH implementation
+K:NA Move sysctl_sctp_[rw]mem definitions to protocol.
+Patch Implement the Supported Extensions Parameter
+K:NA net/sctp/socket.c: make 3 variables static
+K:NA Make sctp_addto_param() static.
+Patch Rewrite of sctp buffer management code
+K:NA Add paramters validity check for ASCONF chunk
+K:NA Discard OOTB packetes with bundled INIT early.
+K:NA Clean up OOTB handling and fix infinite loop processing
+K:NA Explicitely discard OOTB chunks
+K:NA Send ABORT chunk with correct tag in response to INIT ACK
+K:NA Validate buffer room when processing sequential chunks
+K:NA Convert bind_addr_list locking to RCU
+K:NA Add RCU synchronization around sctp_localaddr_list
+K:NA Fix to handle invalid parameter length correctly
+K:NA Abort on COOKIE-ECHO if backlog is exceeded.
+K:NA Correctly disable listening when backlog is 0.
+K:NA Do not retransmit chunks that are newer then rtt.
+K:NA Uncomfirmed transports can't become Inactive
+K:NA Pick the correct port when binding to 0.
+K:NA Use net_ratelimit to suppress error messages print too fast
+K:NA Fix to encode PROTOCOL VIOLATION error cause correctly
+K:NA Fix sctp_addto_chunk() to add pad with correct length
+K:NA Assign stream sequence numbers to the entire message
+K:NA properly clean up fragment and ordering queues during FWD-TSN.
+K:NA remove useless code in function sctp_init_cause
+K:NA drop SACK if ctsn is not less than the next tsn of assoc
+K:NA IPv4 mapped addr not returned in SCTPv6 accept()
+K:NA Fix whitespace errors.
+
+lksctp-2.6.22-1.0.7: Thu Jul 12 12:24:14 EDT 2007
+K:NA Don't disable PMTU discovery when mtu is small
+K:NA Flag a pmtu change request
+K:NA Update pmtu handling to be similar to tcp
+K:NA Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails
+K:NA Allow unspecified port in sctp_bindx()
+K:NA Correctly set daddr for IPv6 sockets during peeloff
+K:NA Do not include ABORT chunk header in the notification.
+K:NA Correctly copy addresses in sctp_copy_laddrs.
+K:NA Prevent OOPS if hmac modules didn't load
+K:NA Set assoc_id correctly during INIT collision.
+K:NA Re-order SCTP initializations to avoid race with sctp_rcv()
+K:NA Fix the SO_REUSEADDR handling to be similar to TCP.
+K:NA Verify all destination ports in sctp_connectx.
+K:NA Fix sctp_getsockopt_local_addrs_old() to use local storage.
+K:NA Implement SCTP_MAX_BURST socket option.
+K:NA Implement sac_info field in SCTP_ASSOC_CHANGE notification.
+K:NA Honor flags when setting peer address parameters
+K:NA Implement SCTP_ADDR_CONFIRMED state for ADDR_CHNAGE event.
+K:NA Implement SCTP_PARTIAL_DELIVERY_POINT option.
+K:NA Implement SCTP_FRAGMENT_INTERLEAVE socket option
+K:NA Do not interleave non-fragments when in partial delivery
+K:NA Unmap v4mapped addresses during SCTP_BINDX_REM_ADDR operation.
+K:NA Fix assertion (!atomic_read(&sk->sk_rmem_alloc)) failed message
+K:NA Correctly reset ssthresh when restarting association
+K:NA Reset some transport and association variables on restart
+K:NA Increment error counters on user requested HBs.
+K:NA Cleanup stale data during association restart
+K:NA Strike the transport before updating rto.
+K:NA Fix connection hang/slowdown with PR-SCTP.
+K:NA Force update of the rto when processing HB-ACK
+K:NA Fix SACK sequence during shutdown.
+K:NA Correctly handle unexpected INIT-ACK chunk.
+K:NA Verify some mandatory parameters.
+K:NA Set correct error cause value for missing parameters
+K:NA Fix err_hdr assignment in sctp_init_cause.
+T:NA Add support for sctp_getaddrlen() API.
+K,T:NA Fix typo adaption -> adaptation as per the latest API draft.
+K:NA Don't export include/linux/sctp.h to userspace.
+K,T:NA Add support for SCTP_CONTEXT socket option.
+K:NA Enable auto loading of SCTP when creating an ipv6 SCTP socket.
+K:NA Handle address add/delete events in a more efficient way.
+K:NA SCTP endianness annotations.
+K:NA Cleanup of the sctp state table code.
+K:NA Remove temporary associations from backlog and hash.
+K:NA Correctly set IP id for SCTP traffic.
+K:NA Always linearize packet on input.
+K:NA Fix the RX queue size shown in /proc/net/sctp/assocs output.
+K:NA Fix receive buffer accounting.
+K:NA Do not timestamp every SCTP packet.
+K:NA Use correct mask when disabling PMTUD.
+K:NA Include sk_buff overhead while updating the peer's receive window.
+K:NA Enable Nagle algorithm by default.
+K:NA Remove multiple levels of msecs to jiffies conversions.
+K:NA Use the flags value that is passed as an arg to sctp_accept.
+K:NA Fix IPv6 address flag setting when doing peel-off/accept.
+K:NA Cleanup nomem handling in the state functions.
+K:NA Extend /proc/net/sctp/snmp to provide more statistics.
+K:NA Convert SCTP to use the new HMAC template and hash interface.
+K:NA Fix sctp_primitive_ABORT() call in sctp_close().
+K:NA Fix sctp_make_abort_user() to avoid use of buggy
+ get_user_iov_size().
+K:Bug 1502698 ADDIP: Don't use an address as source until it is ASCONF-ACKed.
+K:NA Set chunk->data_accepted only if we are going to accept it.
+K:NA Verify all the paths to a peer via heartbeat before using them.
+K:NA Unhash the endpoint in sctp_endpoint_free().
+K:NA Check for NULL input to sctp_bucket_destroy().
+K:NA Fix persistent slowdown in sctp when a gap ack consumes rx buffer.
+K:NA Send only 1 window update SACK per message.
+K:NA Don't do CRC32C checksum over loopback.
+K:NA Reset rtt_in_progress for the chunk when processing its sack.
+K:NA Reject sctp packets with broadcast addresses.
+K:NA Limit association max_retrans setting in ASSOCINFO setsockopt.
+T:NA updates to linux 2.6.17
+K:NA Allow linger to abort 1-N style sockets.
+K:NA Validate the parameter length in HB-ACK chunk.
+K:NA A better solution to fix the race between sctp_peeloff() and
+ sctp_rcv().
+K:Bug 1439226 Set sk_err so that poll wakes up after a non-blocking connect
+ failure.
+K:NA Fix state table entries for chunks received in CLOSED state.
+K:NA Fix panic's when receiving fragmented SCTP control chunks.
+K:NA Prevent possible infinite recursion with multiple bundled DATA.
+K:NA Allow spillover of receive buffer to avoid deadlock.
+T:NA Fix the type of 'len' argument in sctp_recvmsg() man page.
+
+lksctp-2.6.16-1.0.6: Fri Feb 3 10:54:20 PST 2006
+K:NA Fix 'fast retransmit' to send a TSN only once.
+K:NA Heartbeats exceed maximum retransmission limit.
+K:NA Correct the number of INIT retransmissions.
+K:NA Fix sctp_rcv_ootb() to handle the last chunk of a packet
+ correctly.
+K:NA Fix couple of races between sctp_peeloff() and sctp_rcv().
+K:NA Fix machine check/connection hang on IA64.
+K:NA Fix bad sysctl formatting of SCTP timeout values on 64-bit m/cs.
+K:NA Fix sctp_assoc_seq_show() panics on big-endian systems.
+K:NA sctp doesn't show all associations/endpoints in /proc.
+K:NA Fix sctp_cookie alignment in the packet.
+K:NA Fix potential race condition between sctp_close() and sctp_rcv().
+K,T:NA Add support for SCTP_DELAYED_ACK_TIME socket option.
+K,T:NA Update SCTP_PEER_ADDR_PARAMS socket option to the latest api.
+ draft11.
+
+lksctp-2.6.15-1.0.5: Tue Jan 3 15:49:27 PST 2006
+K:NA Fix SCTP to not return erroneous POLLOUT events.
+K:NA Fix getsockname for sctp when an ipv6 socket accepts a
+ connection from an ipv4 socket.
+K:NA Return socket errors only if the receive queue is empty.
+K,T:NA Include ulpevents in socket receive buffer accounting.
+K:Bug 1350514 Fix ia64 NaT consumption fault with sctp_sideeffect commands.
+K:NA Remove timeouts[] array from sctp_endpoint.
+K:Bug 1350521 Fix potential NULL pointer dereference in sctp_v4_get_saddr.
+K:NA Do not allow unprivileged programs initiating new assocs on
+ privileged ports.
+K:NA Allow SCTP_MAXSEG to revert to default frag point with a '0'
+ value.
+K:NA Fix SCTP_SETADAPTION sockopt to use the correct structure.
+K,T:NA Rename SCTP specific control message flags to use SCTP_ prefix
+ rather than MSG_ prefix.
+
+lksctp-2.6.14-1.0.4: Fri Oct 28 10:56:04 PDT 2005
+T:NA Add sctp_send() API support, testcases and manpage.
+T:NA Add preprocessor constants for PR-SCTP, ADDIP & CANSET_PRIMARY
+K,T:NA Fix SCTP socket options to work with 32-bit apps on 64-bit
+ kernels.
+K,T:NA Fix sctp_get{pl}addrs() API to work with 32-bit apps on 64-bit
+ kernels.
+T:NA Ignore MSG_CMSG_COMPAT flag leaked to 32-bit userspace with
+ 64-bit kernels <= 2.6.13.
+K,T:Bug 1122994Fix SCTP_SHUTDOWN notifications for 1-1 style sockets.
+
+lksctp-2.6.13-1.0.3: Thu Sep 1 10:54:22 PDT 2005
+T:NA Update to 2.6.13
+K:NA Fix potential NULL pointer dereference while handling an ICMP
+ error.
+K:NA Make init & delayed sack timeouts configurable by user.
+K:NA Fix incorrect setting of sk_bound_dev_if when binding/sending
+ to a ipv6 link local address.
+K:NA Support IP_FREEBIND socket option and ip_nonlocal_bind sysctl.
+K:NA Extend the info exported via /proc/net/sctp to support
+ netstat for SCTP.
+K:NA Support SO_BINDTODEVICE option on incoming packets.
+K:Bug 120804 Fix bug in restart of peeled-off association.
+K,T:NA sctp_connectx() support.
+T:NA Increase sk_sndbuf to address send buffer accounting changes.
+T:NA Update SCTP internet drafts in doc directory
+T:NA Fix inconsistencies in license stmt in the library files.
+K:Bug 1155119 Add sctp send buffer accounting.
+K:NA Replace incorrect use of dev_alloc_skb with alloc_skb in
+ sctp_packet_transmit().
+K:NA Fix bug in sctp_init() error handling code.
+K:NA Use ipv6_addr_any() rather than ipv6_addr_type() in
+ sctp_v6_is_any().
+T:Bug 1150885 Fix subscript out of range bug in sctp_test.c
+K:Bug 1158878 Implement Sec 2.41 of SCTP Implementers guide.
+K:Bug 1121085 Fix SCTP_ASSOCINFO getsockopt for 1-1 style sockets.
+K:Bug 1155130 Add sctp receive buffer accounting.
+
+lksctp-2.6.10-1.0.2: Thu Dec 30 15:55:27 PST 2004
+Bug 1074664 Fix sctp_getladdrs() to return valid local addresses on an
+ endpoint that is bound to INADDR_ANY or inaddr6_any.
+NA Update to 2.6.10
+Bug 1028605 Fix misc. issues in SCTP_PEER_ADDR_PARAMS set socket option.
+NA Fix bug in setting ephemeral port while adding a bind address.
+Bug 1090392 Clean up the T3_rtx timer when deleting a transport.
+Patch 1090027Implementation of SCTP IG Section 2.35
+Bug 905731 Validate and respond to invalid chunk/parameter lengths.
+Bug 1085959 Treat ICMP protocol unreachable errors from non-SCTP capable
+ hosts as ABORTs.
+NA Code cleanup: remove unused code and make needlessly global code
+ static
+Bug 1058857 Fix potential null pointer dereference in sctp_err_lookup().
+Bug 982971 Validate fromlen/msg_flags in sctp_recvmsg before dereferencing.
+Bug 860345 Fix invalid msg length to sctp_sendmsg in sctp_xconnect.c
+Bug 1008149 Fix HEARTBEAT_ACKs being sent to wrong dest. ip address in a
+ multihoming scenario after failback. (Jorge)
+NA Update any transports that are caching a deleted address as
+ a source address.
+NA Update cwnd/ssthresh as per the sctpimpguide modifications.
+NA Adaption layer indication support
+NA Change sctp_assoc_t to a sized type(s32)
+NA Update to 2.6.9
+NA Update to 2.6.8-rc2
+NA Mark chunks as ineligible for fast retransmit after handling
+ retransmit.
+Bug 995918 Fix missing '+' in the computation of sack chunk size in
+ sctp_sm_pull_sack().
+NA Use idr_get_new_above() with a starting id of 1 to avoid returning
+ an associd of 0.
+Bug 968562 Fix issues with handling stale cookie error over multihoming
+ associations.
+Bug 991991 Fix data not being delivered in SHUTDOWN_SENT state.
+Bug 979178 Set/Get default SCTP_PEER_ADDR_PARAMS for endpoint when associd
+ and peer address are 0.
+Bug 965359 Fix missing VTAG validation on certain incoming packets.
+Bug 965278 Fix to wakeup blocking connect() after max INIT retries failed.
+Bug 965276 Fix the use of cached non-zero vtag in a INIT that is resent
+ after a stale cookie error.
+Bug 962587 Fix poll() on a 1-1 style socket so that it returns when the
+ association is aborted by peer.
+Bug 962530 Add association states to netinet/sctp.h
+Bug 954271 Fix to not start a new association on a 1-many style sendmsg()
+ with MSG_EOF/MSG_ABORT flag and no data.
+Bug 948012 Fix to not setup a new association if the endpoint is in
+ SHUTDOWN_ACK_SENT state and recognizes that the peer has restarted.
+
+lksctp-2.6.6-1.0.1: Tue May 11 10:08:56 PDT 2004
+Bug 949429 Fix multihomed connection failures on 64bit systems. (Vlad)
+Bug 932698 fix accessing gap ack blocks array with -ve index in
+ sctp_outq_sack().
+Bug 932692 memset parameter misordering.
+NA Fix the 3rd arg to sctp_recvmsg() to size_t instead of a ptr.
+NA Rename SCTP_ADDR_REACHBLE as SCTP_ADDR_AVAILABLE.
+NA Fix bugs in handling overlapping INIT and peer restart over a
+ multi-homed association.
+NA SCTP crc table can be static const (Stephen Hemminger)
+NA Update sctp_test message sizes to match the new frag point of
+ 1452 bytes for AF_INET sockets with 1500 mtu.
+NA Propagate error from sctp_proc_init. (Olaf Kirch)
+Patch 751951 Partial Reliability extension support.
+NA Cleanup sctp_packet and sctp_outq infrastructure.
+NA Avoid the use of constant SCTP_IP_OVERHEAD to determine the max
+ data size in a SCTP packet.
+NA Add MSG_EOF to netinet/sctp.h
+NA Use id to ptr translation service to assign and validate assoc ids.
+NA Update sctp_ulpevent structure.
+NA Fix typo in entry name of remove_proc_entry() call.
+NA Enable association change and data io events in sctp_test.
+NA Add set_peer_primary interactive option to sctp_darn.
+NA Use AM_CFLAGS/AM_LDFLAGS in Makefile.am's.
+NA Avoid the use of hackish CONFIG_IPV6_SCTP__ option.
+NA Don't do any ppid byte-order conversions as it is opaque to SCTP.
+
+lksctp-2.6.3-1.0.0:
+Bug 905331 Fix incorrect sinit_max_init_timeo behavior. (samudrala)
+NA Force enable crypto options needed by SCTP (samudrala)
+NA Update to 2.6.3 (samudrala)
+NA Add support to get/set primary addr of an assoc to sctp_darn.
+NA Add __BEGIN_DECLS/__END_DECLS to sctp.h (Ian)
+NA Fix sctp_getladdrs()/sctp_getpaddrs() API so that the port value
+ in the returned addresses is in network byte order. (samudrala)
+NA Fix SCTP_INITMSG set socket option so that a parameter with 0
+ value will not change its current value. (samudrala)
+NA Use __get_free_pages() to allocate ssnmap to avoid kmalloc's
+ 128K limit. (samudrala)
+
+lksctp-2.6.2-0.9.0:
+NA Updated withsctp to capture and replace TCP_NODELAY
+ setsockopt() (samudrala)
+Patch 890787 RPM packaging bugfixes. (FiX)
+NA Removed the deprecated ADLER32 checksum support. (samudrala)
+NA Update to 2.6.2 (samudrala)
+NA Added manpages for SCTP. (samudrala)
+Patch 887176 autoconf cleanup/ Initial RPM packaging (FiX)
+Patch 878417 Added new 1-1 style API testcases. (damien, samudrala)
+NA Add sysctl parameters to change socket receive/send buffer sizes
+ and update the default receive buffer to 65535 bytes.
+NA provide valid tos and oif values for ip_route_output_key.
+NA Fix bugs in byte order conversion while processing certain
+ address related socket options. (samudrala)
+Patch 869098 ADDIP: T4 RTO timer support. (kevin.gao)
+Patch 865250 withsctp: a tool to replace TCP with SCTP. (La Monte)
+NA Enable shared libraries in lksctp-tools. (FiX)
+Patch 843544 ADDIP: Process incoming ASCONF_ACK chunks. (kevin.gao)
+NA Add a testcase to verify that a SHUTDOWN_COMP notification is
+ received on a SHUT_RW one-to-one style socket. (samudrala)
+NA Add peeloff test to src/apps. (samudrala)
+NA Fix overflow in the macros JIFFIES_TO_MSECS/MSECS_TO_JIFFIES
+ when used with large values. (samudrala)
+NA Fix the duplicate increment of checksum error counter and
+ counting bad packet errors as checksum errors. (samudrala)
+NA Fix to free assocs in the acceptq of a one-to-one style socket
+ that is closed. (samudrala)
+NA ADDIP: Add sysctl parameter to enable/disable addip (samudrala)
+NA Fix extra semicolon bug in sctp_cacc_skip_3_1() (Ed Rupp)
+Patch 831522 ADDIP: Testcase for delete IP (kevin.gao)
+Patch 822546 ADDIP: Process ASCONF and respond with ASCONF_ACK (kevin.gao)
+
+lksctp-2.6.0-test7-0.7.4:
+NA Update SCTP tests so that they can be run under LTP (samudrala)
+NA Update to 2.6.0-test7 (samudrala)
+Patch 809137 ADDIP: Support to create ASCONF_ACK chunk. (kevin.gao)
+Patch 798988 ADDIP: ASCONF chunk send support. (kevin.gao)
+NA lksctp-tools tree re-organization (samudrala)
+NA Fix malloc calls in kernel tests with no error checks. (samudrala)
+NA Fix bugs in conversions between msecs and jiffies. (samudrala)
+NA Update to 2.6.0-test6 (samudrala)
+PARISC64 Convert tv_add() from a static inline to macro to fix an
+ obscure assembler issue with parisc64 (samudrala)
+NA Update to 2.6.0-test5 (samudrala)
+PPC64 port Use correct types for args passed to sctp_recvmsg() calls.
+PPC64 port Change the last arg of sctp_opt_info() to match the last arg
+ of getsockopt(). (samudrala)
+PPC64 port Don't overload the optval of ADDRS_NUM socket options with
+ different types for input and output. (samudrala)
+
+lksctp-2_6_0-test4-0_7_3:
+NA draft 07 API: (samudrala)
+ - listen() with 0 backlog disables listening.
+ - By default all notifications are turned off even with
+ one-to-many(UDP) style sockets.
+Bug 799468 Fixes for a couple of issues with ssnmap allocation. (samudrala)
+NA Convert sctp_param2sockaddr() and sockaddr2sctp_addr to address
+ family specific routines. (samudrala)
+NA draft 07 API: sctp_bindx() update. (samudrala)
+Patch 791660 ADDIP: SCTP_SET_PEER_PRIMARY socket option support. (kevin.gao)
+NA Update to 2.6.0-test4 (samudrala)
+NA draft 07 API: getp/laddrs, freep/laddrs changes (samudrala)
+NA draft 07 API: sctp_recvmsg() arg type change. (samudrala)
+NA draft 07 API: sctp_peeloff() takes associd, not a ptr (samudrala)
+Patch 784504 ADDIP: Testcase to verify basic ADDIP functionality. (kevin.gao)
+Bug 787008 Bugs in sysctl set/get of sctp rto parameters. (samudrala)
+NA Update to 2.6.0-test3 (samudrala)
+Bug 783176 Fix to avoid large kmalloc failures on 64bit platforms (samudrala)
+Patch 776732 ADDIP basic infrastructure support. (ardelle.fan)
+Patch 775227 sctp_recvmsg() API support. (rlayer)
+
+lksctp-2_6_0-test1-0_7_2:
+NA Set output interface for link-local v6 addresses (jgrimm)
+Patch 769844 Add V6 and freebsd support to sctp_test (rlayer)
+Patch 772062 Support IPV6_V6ONLY socket option. (ardelle.fan)
+Patch 757888 Support v4-mapped-v6 addresses (ardelle.fan)
+NA Update API names to be compatible with draft07 (samudrala)
+NA Update to 2.6.0-test1 (samudrala)
+Patch 767208 Shutdown transport selection fix. (rlayer)
+Patch 769792 Fix for panic on recvmsg() with MSG_PEEK & misc stuff (samudrala)
+Patch 765676 Fix nasty race on skb destructor with AF_PACKET sockets (jgrimm)
+
+lksctp-2_5_72-0_7_1:
+Patch 759352 Perf: Don't search for gap ack blocks past highest TSN (jgrimm)
+Patch 758202 Perf: Remove update_pending() from SACK path (jgrimm)
+NA Update to 2.5.72
+NA Fix hlist bug introduced by mainline kernel (jgrimm)
+NA sctp_xconnect test tool (rlayer)
+Patch 729089 ASSOCINFO/RTOINFO sockopts (pems & rlayer)
+NA Update to 2.5.71 (jgrimm)
+Bug 754129 Incorrect VTAG in stale cookie error chunk (samudrala)
+Patch 749587 Change rto sysctl vars to milliseconds (rmlayer)
+Patch 752321 Add kamikaze test. (ardelle.fan)
+Bug 752808 Bug fix for input loop exiting too early on TCP-style (jgrimm)
+
+lksctp-2_5_70-0_7_0:
+NA Fix hostname parameter handling, should ABORT (jgrimm)
+NA Fix ft_frame_unkparam testcase (rlayer)
+Bug 751458 Fixes from InterOp (jgrimm, samudrala)
+Bug 746295 Fix div by 0 in sctp_jitter (jgrimm)
+NA Make T5 timer cleanup SHUTDOWN-PENDING state. (jgrimm)
+Patch 744633 /proc interface to display associations/endpoints (samudrala)
+NA Update to 2.5.70 kernel. (samudrala)
+NA sctp_getladdrs(), sctp_getpaddrs() bug fixes. (samudrala)
+Patch 738592 sctp_sendmsg() api support. (ardelle.fan)
+Patch 738550 SCTP_SHUTDOWN_EVENT notification support. (samudrala)
+NA Rename struct sctp_protocol as sctp_globals (samudrala)
+Patch 737395 SCTP_GET_PEER_ADDR_INFO socket option. (samudrala)
+Bug 695324 Report error cause in CANT_STR_ASSOC (ardelle.fan)
+Bug 695322 Stale cookie might not be first err cause (ardelle.fan)
+Patch 735933 Support for socket options that take addr & associd (samudrala)
+Patch 718726 Add CACC frametest (ardelle.fan)
+NA slab cache for chunks & bind_bucket (jgrimm)
+NA Update to 2.5.69 kernel. (samudrala)
+Patch 733320 SCTP ECN & IPv6 (jgrimm)
+NA Bug in get_peer_addr_params. (jgrimm, report by yfj@stanford.edu)
+Patch 730924 Add sinfo_timetolive support. (jgrimm)
+Patch 730461 SO_LINGER support for TCP-style sockets. (samudrala)
+Bug 729234 Initialize missing v4 fields of a v6 accept socket (samudrala)
+Bug 729652 Free chunk(s) when primitive_SEND fails (jgrimm)
+Patch 704841 SEND_FAILed for fragmented messages (jgrimm, ardelle.fan)
+Patch 727821 sendmsg() updates for TCP-style sockets. (samudrala)
+Patch 727454 Add control chunk bundling (jgrimm)
+Patch 718726 Add SFR-CACC support. (ardelle.fan)
+Patch 726343 Add SCTP_MAXSEG support. (jgrimm)
+NA Add some macros to help cleanup code. (jgrimm)
+Patch 725367 Fix for poll() on a TCP-style listening socket. (samudrala)
+Patch 725219 Add per message fragment tracking (jgrimm)
+NA Update to 2.5.68 kernel. (samudrala)
+
+lksctp-2_5_67-0_6_9:
+Patch 723414 Handle accept() of a CLOSED association. (samudrala)
+Patch 722206 shutdown() support for TCP-style sockets. (samudrala)
+Bug 722169 Fix can't send to routed ipv6 address bug (jgrimm)
+NA Fix GFP_KERNEL allocation while spinlock. (jgrimm)
+Patch 721330 Allow v4 private to v4 global association. (jgrimm)
+Patch 720930 getsockname/getpeername support for TCP-style sockets (samudrala)
+Patch 719232 optimization: csum_update_copy && ulpq short-circuit (jgrimm)
+NA Update to 2.5.67 kernel. (samudrala)
+Patch 717587 Use kernel crypto api (jgrimm)
+Patch 714270 listen backlog support for TCP-style sockets. (samudrala)
+Patch 712929 Fix SACK bundling bug & a few minor fixes (jgrimm)
+Patch 711590 Add V6_LINKLOCAL & sin6_scope_id support. (jgrimm)
+Patch 711584 Add '--interface' option to sctp_darn tool. (jgrimm)
+Patch 704841 Add SEND_FAILED support (ardelle.fan)
+NA Update to 2.5.66 kernel (jgrimm)
+Patch 709527 Add icmpv6 handler and PKT_TOOBIG support. (jgrimm)
+
+lksctp-2_5_65-0_6_8:
+Patch 706470 Bundle SACK with outgoing DATA (jgrimm)
+NA Add --echo option to sctp_darn (jgrimm)
+NA Update to 2.5.65 kernel and config changes. (jgrimm)
+Patch 702439 New kernel test to verify TCP-style socket interfaces. (samudrala)
+Bug 701294 Invalid associd passed to getsockopt() in sctp_darn. (samudrala)
+
+lksctp-2_5_64-0_6_7:
+NA Update to 2.5.64 kernel. (samudrala)
+Bug 699299 Panic in close(). (jgrimm)
+Patch 698437 frametest for TCP-style sockets. (samudrala)
+Patch 698877 Receiver SWS prevention. (jgrimm)
+Patch 689872 Nagle-like support for SCTP. (ardelle.fan)
+Patch 694884 accept() support for TCP-style sockets. (samudrala)
+NA Bug fix from mailing list (Norbert Kiesel)
+Patch 689872 SCTP_NODELAY testcases (ardelle.fan)
+
+lksctp-2_5_63-0_6_6:
+NA Update to 2.5.63 kernel. (samudrala)
+Patch 692590 Add set/getsockopt SET_PEER_PRIMARY_ADDR (jgrimm)
+Bug 601470 Fix PF_INET sockets advertise v6 support bug (jgrimm)
+NA Fix testframe for non-SMP build (jgrimm)
+Bug 688408 Fix testcases for v4 only configurations (jgrimm)
+Patch 677351 Add getsockopt for DEFAULT_SEND_PARAM (ardelle.fan)
+Patch 689446 Renege for "fills gap" case. (jgrimm)
+Bug 611888 Round-robin retransmit path updates. (samudrala)
+NA Update to 2.5.61 kernel. (samudrala)
+NA Update to 2.5.60 kernel. (samudrala)
+Bug 649355 v6 source address selection support. (samudrala)
+Patch 680361 Add testcase for partial data delivery. (jgrimm)
+Patch 677351 SET_DEFAULT_SEND_PARAM setsockopt. (ardelle.fan)
+Patch 681914 Skinny up ulpevent and support sinfo_cumtsn (jgrimm)
+Patch 685246 Partial Data Delivery. (jgrimm).
+Patch 683736 Override primary destination with MSG_ADDR_OVER (ardelle.fan)
+Patch 630124 SCTP snmp mib statistics update/display support. (samudrala)
+Patch 686131 Move duplicate TSN tracking to tsnmap & cleanup (jgrimm)
+NA C99 struct initializer cleanup. (Art Haas)
+
+lksctp-2_5_59-0_6_5:
+Patch 674359 Handling for Invalid Stream in INIT & missing cookie. (jgrimm)
+Patch 676473 Add v6 scoping testcases. (jgrimm)
+Bug 677107 af->dst_saddr doesn't fill in the port (samudrala)
+Patch 676468 Cleanup of assoc bind addr list initialization (samudrala)
+Patch 678481 Large Message Fragmentation support (jgrimm)
+Bug 679839 Kconfig can emit bad config of ipv6=m, sctp=y (jgrimm)
+
+lksctp-2_5_59-0_6_4:
+Patch 673715 Fix to update rwnd on partial reads. (samudrala)
+Patch 673678 Minor fixes to overlapping init. (jgrimm)
+Patch 673309 Minor fixes to icmp error handler. (samudrala)
+Bug 672878 Free chunks in rtx & control queues on teardown.(samudrala)
+Patch 672759 Advisory marker as 'unsafe' for unload. (jgrimm)
+Patch 671916 Heartbeat timer during shutdown fixes (jgrimm)
+Patch 670970 Path mtu support for v4 addresses. (samudrala)
+NA Update to 2.5.59 kernel. (samudrala)
+Patch 667038 Add heartbeat jitter (ardelle.fan)
+Patch 670020 Remove hardcoded stream limits (jgrimm)
+NA Update to 2.5.56 kernel. (samudrala)
+Patch 662296 Handle ip re-assembled non-linear skb's (samudrala)
+Patch 663633 get/free paddrs and laddrs support (ardelle.fan)
+Bug 664112 Retransmitting already gap-acked TSNs (jgrimm)
+NA Update to 2.5.53 kernel. (samudrala)
+Bug 667037 ft_frame_rwnd_receiver fail with v4 only (ardelle.fan)
+
+lksctp-2_5_52-0_6_3:
+NA Update to 2.5.52 kernel. (samudrala)
+Patch 652802 Window update SACK support. (samudrala)
+Patch 651063 Fixes for compiler issues with gcc 3.2 (samudrala)
+Patch 649819 Notifier registration for v6 addr events. (samudrala)
+Patch 638235 Stale cookie support. (ardelle.fan)
+Patch 648103 v6 source address selection support. (samudrala)
+Bug 645067 memcpy in sctp_sendmsg() may copy too much. (samudrala)
+NA Update to 2.5.50 kernel. (samudrala)
+Patch 644936 SCTP_INITMSG socket option. (samudrala)
+NA Update to 2.5.49 kernel. (samudrala)
+Bug 641066 Bad dereference in sctp_cmd_assoc_failed. (samudrala)
+Patch 639177 MSG_PEEK support for recvmsg(). (samudrala)
+
+lksctp-2_5_47-0_6_2:
+Patch 637943 MSG_EOR support for recvmsg(). (samudrala)
+NA Update to 2.5.47 kernel. (samudrala)
+Patch 636734 v6 autobind (jgrimm)
+Patch 635797 Blocking connect() support. (samudrala)
+Patch 634730 udp-style connect(non-blocking) support. (samudrala)
+NA Update to 2.5.46 kernel. (samudrala)
+Patch 555335 Peer address parameters socket option (ardelle)
+NA Update to 2.5.45 kernel. (samudrala)
+Patch 631750 sctpParam_t cleanup (jgrimm)
+Bug 587078 sctp_process_init() can fail (jgrimm)
+Patch 633338 Handle HOST_NAME_ADDR parm and misc. (jgrimm)
+Patch 625413 sockaddr_storage_t cleanup (jgrimm)
+Patch 635246 short circuit "no route" case (jgrimm)
+Bug 581734 PF_INET6 listen can't receiving v4 addresses (jgrimm)
+
+lksctp-2_5_44-0_6_1:
+Patch 628901 Initial Source address selection support. (samudrala)
+Bug 611930 Lost CWR scenario fix (jgrimm)
+NA 2.5.44 (jgrimm)
+Patch 628333 SNMP MIB infrastructure for SCTP. (nivedita)
+Patch 628318 Checks for tcp-style sockets. (nivedita)
+Bug 547270 Retain the order of retransmission. (daisyc)
+Patch 622919 Handle User initiated ABORT. (ardelle.fan)
+Bug 611927 Bug in the calculation of highest new tsn in sack. (samudrala)
+Bug 611916 Data can end up getting sent ahead of pend. rtx data (jgrimm)
+NA Update to 2.5.43 kernel. (samudrala)
+Bug 623286 SHUTDOWN_COMPLETE has 0 vtag on lost SDC + restart. (samudrala)
+Patch 601756 VTAG checks for ABORT and SHUTDOWN_COMPLETE chunks. (ardelle.fan)
+Patch 619993 Fixes a couple of sctp_peeloff() issues. (samudrala)
+Bug 611919 Fast retranmist should ignore cwnd limit. (daisyc)
+Bug 611840 Restart address needs to check INIT and happen earlier (jgrimm)
+
+lksctp-2_5_41-0_6_0:
+NA Update to 2.5.41 kernel (samudrala)
+Bug 621054 v6 kernel tests pass without IPv6 configured. (daisyc)
+NA Update to 2.5.40 kernel (jgrimm)
+NA Split into user/kernel repositories (inaky, daisyc)
+Bug 611928 Alloc GFP_KERNEL with locks held (jgrimm)
+Bug 602650 Dropping packets > frag_point (jgrimm, samudrala)
+Patch 601367 Handle Unrecognized Parms (daisyc)
+Patch 609744 Add abort and shutdown to sctp_darn (ardelle.fan)
+Bug 604251 Association freed twice (jgrimm)
+Bug 611835 Fix Restart address check (jgrimm)
+
+lksctp-2_5_29-0_5_0:
+Patch 588249 misc. user header file fixes (jgrimm)
+
+lksctp-2_5_29-0_4_99:
+Patch 582166 sctp_peeloff() support. (samudrala)
+Bug 583874 sendmsg/init with bad buf. has leak (jgrimm)
+Patch 581963 Handle select/poll syscalls (daisyc)
+Bug 583798 Need GFP_ATOMIC when BH disabled (samudrala)
+Bug 585351 MSG_UNORDERED not set on fragmented chunks (samudrala)
+Patch 585474 Remove old DEFAULT_STREAM sock opt (jgrimm)
+Bug 585653 Fix V6INADDR_ANY to choose a saddr (jgrimm)
+Bug 585929 more leaks in sendmsg() on error cases. (samudrala)
+Patch 574420 overlapping init/restart (dajiang, jgrimm)
+Bug 581992 zero probe shouldn't error association (samudrala)
+Patch 587986 move to Linux 2.5.29 (samudrala)
+
+lksctp-2_5_24-0_4_12:
+Patch 569943 graceful shutdown of an individual association. (samudrala)
+Patch 572054 move to linux kernel 2.5.24. (samudrala)
+Bug 574069 bugs in fragmentation & reassembly. (samudrala)
+Patch 579301 check for No User Data error and testcase (jgrimm)
+Bug 574071 less strict rwnd check at rcvr (samudrala)
+Patch 579525 SCTP_AUTOCLOSE socket option. (samudrala)
+Patch 575712 modify sctp_darn tool to use select (daisyc)
+NA misc.: cleanup jiffies decl., update docs. (jgrimm)
+Patch 581745 getsockname needs sk->sport (jgrimm)
+Patch 582273 handle DATA while in SHUTDOWN-SENT (jgrimm)
+Bug 581997 sctp_wait_for_sndbuf fault (jgrimm)
+Patch 573958 Overlapping Init testcases (dajiang)
+Patch 582905 misc: remove md5 files. update cause code values (jgrimm)
+
+lksctp-2_5_15-0_4_11:
+Patch 560341 assoc_hash and more locking (jgrimm)
+Bug 541062 local_addr_list not not writer safe (jgrimm)
+Patch 564637 new ep_hash and locking down address list read/writes (jgrimm)
+Patch 565087 protect against timer overfiring (jgrimm)
+Patch 565935 Collapse ep/asoc hash links into common substructure (jgrimm)
+Bug 565868 Ctl-sock (OOTB) traps sending to ipv6 dest. (jgrimm)
+Bug 565878 Xmit to wrong peer when no asoc. (jgrimm)
+Patch 565686 Update RTO upon Heartbeat ACK. (samudrala)
+Patch 567028 Cleanup unneeded atomic_t fields (jgrimm)
+Patch 567061 Some sctp-socket-04.txt updates (jgrimm)
+Patch 567646 Combine sctp_func_t/sctp_af_specific_t (jgrimm)
+Patch 568562 Sysctl support for RFC 2960 variables (jgrimm)
+Patch 567514 SCTP_SET_EVENTS sock options (samudrala)
+Patch 567492 block/non-block send and SNDBUF/RCVBUF (daisyc)
+
+lksctp-2_5_15-0_4_10:
+Patch 561757 congestion control, handle SACKs indicating renege (samudrala)
+Patch 561632 v4 scoping rules (daisyc)
+lksctp-2_5_15-0_4_9:
+Patch 554705 Locking phase 1 (off the BH, use socklock and backlog) (jgrimm)
+Bug 550363 Shutdown handling of CTSN incorrect (jgrimm)
+Patch 558565 testframe ipv4 only, doesn't compile (samudrala)
+Patch 556572 Fix INADDR_ANY and some IPv4 scoping (daisyc)
+Patch 559801 Cleanup old locking stuff and various naming/style (jgrimm)
+
+lksctp-2_5_15-0_4_8:
+Patch 557034 Port to 2.5.15 (samudrala)
+Patch 550903 sys_bindx removal (inaky, samudrala)
+
+lksctp-2_4_18-0_4_8:
+Patch 546328 sctp_transport cleanup (jgrimm)
+Bug 545852 sk->err cleanup (samudrala)
+Bug 547147 association leaks the inqueue->in_progress chunk (jgrimm)
+Bug 541065 fix port_rover race conditition in bind path (jgrimm)
+Patch 544577 heartbeat ack and failover (dajiang)
+NA Make lksctp a module (inaky)
+NA bindx over sockopt (inaky)
+Patch 547885 Split out v6 code and cleanup module patch (jgrimm)
+Patch 544583 ft_frame_hbACK updates (dajiang, huang)
+Patch 547340 fix testframe for "run once" (samudrala)
+Patch 548772 sctp_lock primitives (jgrimm)
+Patch 547319 naming cleanup in statefuns (daisyc)
+Patch 549266 sctp_lock unittests (jgrimm)
+Patch 548815 Disable fragments option and more tests. (samudrala)
+Patch 550400 Add OOTB testcase (daisyc)
+Patch 550520 transport & association error thresholds (samudrala)
+NA fix ft_frame_init_timer to not conflict with OOTB (jgrimm)
+Patch 549356 Small fixes and cleanup of bindx code (inaky)
+Patch 549360 bindx through sockopt (inaky)
+Patch 551716 Start using sctp_opts field instead of endpoint (jgrimm)
+Patch 551657 RTT Measurements and RTO updates (samudrala)
+Patch 552084 sctp_endpoint_common (jgrimm)
+Patch 553100 Testcase for RTT Measurements (samudrala)
+Bug 553329 Sendmsg + INIT CMSG has path which can corrupt assoc (jgrimm)
+Patch 553394 Move sctp_association to use endpoint_common (jgrimm)
+Patch 553528 rtx and heartbeat failures cleanup (samudrala)
+Patch 553844 OOTB packet processing (daisyc)
+
+lksctp-2_4_18-0_4_7:
+Bug 541198 Old-style retval->state races with CMD (jgrimm)
+Patch 541820 listen auto-bind support (samudrala)
+Patch 543421 Complete removal of retval structs/processing (jgrimm)
+Patch 544908 Object Count Debugging facilities (jgrimm)
+Patch 544806 Fix inqueue leak of chunks (daisyc)
+Patch 544460 Fragmentation/Reassembly support (samudrala)
+
+lksctp-2_4_18-0_4_6:
+Patch 529522 Primary Addr from saddr (jgrimm, daisyc, hui_huang)
+Patch 529530 Use skb_copy_datagram_iovec (samudrala)
+Patch 529961 sctphdr, PARAM constants in net order (jgrimm)
+Patch 529707 Changes to sctp_make_data* interfaces (samudrala)
+Patch 531206 Massive linux/sctp.h changes (jgrimm)
+Patch NA Eliminate sctp_io.h (jgrimm)
+Patch 532575 sctp_opt as a per socket structure (jgrimm)
+Patch 532245 Patch to eliminate tcp_func dependency (samudrala)
+Patch 533351 Update headers to Socket Extensions 03 draft (jgrimm)
+Patch 531647 Initialize MTU from routing information (samudrala)
+Patch NA Update csum I-D. (jgrimm)
+Patch 529783 Send heartbeats (dajiang, hui_huang)
+Bug 529726 SACK response sent to incorrect dest (jgrimm)
+Patch NA More cleanup, mostly naming, dead field removal. (jgrimm)
+Bug 539452 sk->err should have errno as positive value (jgrimm).
+
+lksctp-2_4_18-0_4_5:
+Bug 513536 association lookup can fail (jgrimm)
+NA Unused file/header cleanup (jgrimm)
+NA Move sctp_socket() to testframe (jgrimm)
+Patch 524687 Stop byteswapping the rcv skb part 1 (daisyc)
+Patch 525009 Stop byteswapping the rcv skb part 2 (daisyc)
+NA Change CRC32C per Connectathon (jgrimm)
+Patch 526505 Change crc code to skip checksum field (jgrimm)
+Patch 526177 Incorrect use of skb->end (samudrala)
+Patch 526740 Missing bindx support (samudrala)
+NA A few sctp_darn fixes (jgrimm)
+NA updatelinux_sctp.sh to handle links (loretos)
+Patch 513912 Invalid stream verification (daisyc)
+Patch 528541 ABORT handling during initiation phase (jgrimm)
+Patch 528679 Misc. Cleanup. (jgrimm)
+Patch 528611 Fix testframe skb for fraglist support (samudrala)
+Patch 526156 SCTP_STATUS sockopt (samudrala)
+
+
+lksctp-2_4_17_0-4_4:
+
+Patch 515054 INIT retransmission (jgrimm)
+Patch 511394 Invalid StreamId tests (daisyc)
+ README suggestions (baqaqi)
+Bug 519410 test_kernel spinlock initialization (sridhar)
+Patch 520992 Enable COOKIE-ECHO bundling (jgrimm)
+Patch 520627 Fix autobind twice bug (daisyc)
+Patch 520755 A couple bugs from Debug Memory Allocations (sridhar)
+Patch 521216 Fix bind_addrs_to_raw calling kmalloc(GFP_KERNL) on int. (jgrimm)
+
+lksctp-2_4_17-0_4_3:
+New Update to 2.4.17 (sridhar)
+Patch 512680 Frame test bindx for IPv6 (hui)
+Patch 510317 Failing testcase for source addr bug (daisyc)
+
+lksctp-2_4_1-0_4_3:
+Patch 511028 New CRC32C (dinakarjb)
+Patch 510797 Sendmsg w/associd (jgrimm)
+Patch 499262 Testcase for stream negotiation (daisyc)
+Bug 473322 Sendmsg insists on msg_name (jgrimm)
+
+
+If you would like to follow the day-to-day development of the SCTP
+kernel, refer to:
+
+ http://lists.sourceforge.net/lists/listinfo/lksctp-developers
+
+Post messages for the developers (including bug reports) to
+
+ lksctp-developers@lists.sourceforge.net
+
+If you wish to participate in development, please subscribe to the
+developers' list, drop a note to lksctp-developers.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..88c32f1
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,92 @@
+ HOW TO COMPILE, RUN AND INSTALL
+ -------------------------------
+
+CONTENTS
+--------
+
+The lksctp-tools package is intended for two audiences.
+ 1) SCTP application developers
+ 2) LKSCTP project developers
+
+For SCTP application developers, this package provides the user-level
+C language header files and a library for accessing SCTP specific
+application programming interfaces not provided by the standard sockets.
+
+For LKSCTP project developers, this package provides the functional
+and API regression tests.
+
+For either role, this project provides sample code, utilities, and
+tests that one may find useful.
+
+The below INSTALL directions are provided with in each of these roles.
+
+NOTE: To build, run and install the lksctp-tools package, your system is
+required to be running with linux-2.5.36, or a later version of the
+kernel, configured with the Network options "SCTP Configuration"
+support enabled.
+
+______________________________________________________________________
+
+
+INSTALLATION
+-------------
+Prerequisite: A Linux kernel with SCTP support. This may come stock with
+your distrbution (some day), or you will need to build your own 2.5.36 or
+later kernel.
+
+To install/build the lksctp-tools utilities/tests do the following:
+
+1) Download and install the following binary RPMs from the lksctp sourceforge
+ website at
+ http://sourceforge.net/project/showfiles.php?group_id=26529
+ * lksctp-tools-x.y.z-1.i386.rpm
+ * lksctp-tools-x.y.z-devel-1.i386.rpm
+ * lksctp-tools-x.y.z-doc-1.i386.rpm
+
+ lksctp-tools-x.y.z-1.i386.rpm includes
+ * SCTP run-time library.
+ * Sample SCTP applications: sctp_darn and sctp_test.
+ * withsctp: a tool when used with existing TCP binaries replaces TCP
+ with SCTP.
+
+ lksctp-tools-x.y.z-devel-1.i386.rpm includes
+ * SCTP header file /usr/include/netinet/sctp.h
+ * SCTP man pages.
+ * Source code for sample SCTP applications.
+
+ lksctp-tools-x.y.z-doc-1.i386.rpm includes
+ * SCTP RFC's and internet drafts.
+
+ If you want to run and play with the included sample SCTP applications or
+ develop your own SCTP applications, you can skip the rest of the
+ instructions.
+
+ If you are interested in running the functional regression tests included
+ in the lksctp-tools package, continue with the following instructions.
+
+2) Download and install the following source RPM form the lksctp sourceforge
+ website at
+ http://sourceforge.net/project/showfiles.php?group_id=26529
+ * lksctp-tools-x.y.z-1.src.rpm
+ This will install the lksctp-tools gzipped tarball and RPM spec file.
+
+3) Untar the lksctp-tools directory from the gzipped tarball. This creates a
+ subdirectory called lksctp-tools-x.y.z.
+
+ Ensure you have autoconf, automake and libtool packages installed on your
+ system.
+
+4) Run ./bootstrap
+
+5) Run ./configure
+
+6) Run make
+
+7) To run the SCTP kernel regression tests,
+
+ $ cd src/func_tests
+ $ make v4test (regression tests for the IPv4 socket support)
+ $ make v6test (regression tests for the IPv6 socket support)
+
+8) Run other SCTP test tools/applications in src/apps directory to verify the
+ running SCTP.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..8577184
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,27 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+DISTCLEANFILES += config.h stamp-h libtool
+MAINTAINERCLEANFILES += aclocal.m4 config.h.in configure stamp-h.in \
+ config.h stamp-h
+
+EXTRA_DIST += ChangeLog AUTHORS COPYING COPYING.lib INSTALL \
+ README ROADMAP NEWS \
+ Makefile.vars Makefile.rules Makefile.dirs
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsctp.pc
+EXTRA_DIST += libsctp.pc.in
+DISTCLEANFILES += libsctp.pc
+
+# bin or src products may be required to generate stuff in test/
+SUBDIRS = man bin src doc
+
+ACLOCAL_AMFLAGS=-I m4
+
+# Libtool support
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+## FIXME: Your stuff here
diff --git a/Makefile.dirs b/Makefile.dirs
new file mode 100644
index 0000000..f376712
--- /dev/null
+++ b/Makefile.dirs
@@ -0,0 +1,60 @@
+# -*-makefile-*-
+#
+# Define here directories you want
+
+rootbindir = /bin
+rootsbindir = /sbin
+rootlibdir = /lib
+
+localedir = $(datadir)/locale
+pkgsysconfdir = $(sysconfdir)/@PACKAGE@
+pkgdocdir = $(datadir)/@PACKAGE@
+
+vpkgsysconfdir = $(pkgsysconfdir)/v@VERSION@
+vpkgdatadir = $(pkgdatadir)/v@VERSION@
+vpkglibdir = $(pkglibdir)/v@VERSION@
+vpkgdocdir = $(docdir)/v@VERSION@
+
+# List here all the directories you want listed in the file to be used
+# in your programs:
+
+directories := \
+ localedir \
+ pkgsysconfdir \
+ rootbindir \
+ rootlibdir \
+ rootsbindir \
+ vpkgdatadir \
+ vpkgdocdir \
+ vpkglibdir \
+ vpkgsysconfdir \
+ \
+ bindir \
+ datadir \
+ libdir \
+ pkgdatadir \
+ pkgdocdir \
+ pkglibdir \
+ sbindir
+
+# To modify this target for another language, just copy, paste and
+# modify the target to generate directories.h. We depend on
+# config.status and Makefile.dirs, as anything changed is going to be
+# reflected there.
+
+# This is for generating the list in C/C++
+directories.h: $(top_builddir)/config.status $(top_srcdir)/Makefile.dirs
+ @rm -f $@
+ @echo -n "Creating $@ ..."
+ @echo "#ifndef __$(subst .,_,$@)__" > $@
+ @echo "# define __$(subst .,_,$@)__" >> $@
+ @echo "" >> $@
+ @echo -e $(foreach v,$(directories),$(shell echo 'D_$(v) \"$($v)\"\\n')) \
+ | sed 's/^ *D_/# define D_/' >> $@
+ @echo "#endif" >> $@
+ @echo " done"
+
+DISTCLEANFILES += directories.h
+MAINTAINERCLEANFILES += directories.h
+
+## FIXME: Your stuff here
diff --git a/Makefile.rules b/Makefile.rules
new file mode 100644
index 0000000..9488228
--- /dev/null
+++ b/Makefile.rules
@@ -0,0 +1,21 @@
+# -*-makefile-*-
+#
+# Generate pre-parsed C code.
+%.i: %.c
+ $(COMPILE) -E -c $^ -o $@
+
+.PRECIOUS: %.i
+%.ci: %.i
+ -grep -v -e "^#" -e "^ *$$" $^ | indent > $@
+ mv -f $@ $^
+
+
+## FIXME: Your stuff here
+
+edit = @sed \
+ -e "s|\@bindir\@|$(bindir)|" \
+ -e "s|\@libdir\@|$(libdir)|" \
+ -e "s|\@PACKAGE\@|$(PACKAGE)|" \
+ -e "s|\@LIBWITHSCTP_CURRENT\@|$(LIBWITHSCTP_CURRENT)|" \
+ -e "s|\@LIBWITHSCTP_REVISION\@|$(LIBWITHSCTP_REVISION)|" \
+ -e "s|\@LIBWITHSCTP_AGE\@|$(LIBWITHSCTP_AGE)|"
diff --git a/Makefile.vars b/Makefile.vars
new file mode 100644
index 0000000..068c29c
--- /dev/null
+++ b/Makefile.vars
@@ -0,0 +1,18 @@
+# -*-makefile-*-
+#
+# type: deep, strictness: gnu
+
+MAINTAINERCLEANFILES = Makefile.in
+DISTCLEANFILES = \\\#*\\\# Makefile
+CLEANFILES =
+MOSTLYCLEANFILES = *~ *.[aios] *.bak *.ci *.io
+
+EXTRA_DIST =
+
+LATEX = @LATEX@
+DVIPS = @DVIPS@
+DVIPDFM = @DVIPDFM@
+ENSCRIPTBIN = @ENSCRIPTBIN@
+PS2PDF = @PS2PDF@
+
+## FIXME: Your stuff here
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..62767ee
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,8 @@
+
+The Linux Kernel SCTP Reference Implementation release 0.5.0 is included in
+Linux 2.5 Kernel release 2.5.34 and up.
+
+From release 0.6.0 and on, we will adopt the new build and installation
+process for lksctp users and developers. Please check the INSTALL and
+ROADMAP for more details.
+
diff --git a/README b/README
new file mode 100644
index 0000000..cfabbe5
--- /dev/null
+++ b/README
@@ -0,0 +1,178 @@
+(C) Copyright 2007 Hewlett-Packard Development Company, L.P.
+(C) Copyright IBM Corp. 2001, 2003
+Copyright 2001 Motorola, Cisco, Intel, Nokia, La Monte Yarroll.
+Copyright 2002 Nokia, La Monte Yarroll, Intel.
+
+This is the lksctp-tools package for Linux Kernel SCTP Reference
+Implementation.
+
+This package is intended to supplement the Linux Kernel SCTP
+Reference Implementation now available in the Linux kernel source
+tree in versions 2.5.36 and following. For more information on LKSCTP
+see the below section titled "LKSCTP - Linux Kernel SCTP."
+
+lksctp-tools
+____________
+
+The lksctp-tools package is intended for two audiences.
+ 1) SCTP application developers
+ 2) LKSCTP project developers
+
+For SCTP application developers, this package provides the user-level
+C language header files and a library for accessing SCTP specific
+application programming interfaces not provided by the standard sockets.
+
+For LKSCTP project developers, this package provides the API
+regression and functional tests. Developers should also check
+lksctp_tests package that provides low level kernel tests. These
+are available from git.kernel.org.
+
+For either role, this project provides sample code, utilities, and
+tests that one may find useful.
+
+
+LKSCTP - Linux Kernel SCTP
+__________________________
+
+The Linux Kernel SCTP Reference Implementation is free software; you
+can redistribute it and/or modify it under the terms of the GNU
+General Public License as published by the Free Software Foundation;
+either version 2, or (at your option) any later version. For more
+information on licensing terms, please see the file COPYING in this
+directory.
+
+SCTP (Stream Control Transmission Protocol) is a message oriented,
+reliable transport protocol, with congestion control, support for
+transparent multi-homing, and multiple ordered streams of messages.
+RFC2960 defines the core protocol. The IETF SIGTRAN Working Group
+developed SCTP. The primary architects are Randy Stewart and Qiaobing
+Xie.
+
+The Kernel Reference is first and foremost an exposition of
+RFC2960 and related documents. You will find that the comments and
+variable names tie closely back to the RFC and Internet Drafts.
+
+This work was started by a small team of developers at Motorola.
+Throughout this document, "we" refers to that team. We intend for the
+meaning of "we" to expand to include the whole development community,
+all 27 million programmers on the planet.
+
+The Kernel Reference has loose origins in the SCTP User Space Reference
+by Randy Stewart and Qiaobing Xie.
+
+MANIFEST
+--------
+.
+|-- bin
+|-- doc
+|-- man
+|-- src
+ |-- apps
+ |-- func_tests
+ |-- include
+ | `-- netinet
+ |-- lib
+ |-- testlib
+ `-- withsctp
+
+You may want to check the following files:
+
+COPYING.lib Licensing terms of libsctp
+COPYING Licensing terms of other pieces of the package
+ROADMAP A tour around the files in the distribution of SCTP-tools.
+INSTALL How to install and run this beast.
+ChangeLog What has changed since the last release?
+
+DESIGN GOALS
+------------
+
+- A primary design goal is to reflect RFC 2960 as closely as
+practical. We have changed many names from the user space reference to
+follow the draft as closely as possible. We have also included
+extensive quotes from the draft adjacent to the code which implements
+them.
+
+- The other primary design goal is to integrate Linux kernel data
+structures and idioms as much as possible. The test framework (in
+directory test/) provides many of the functions which would otherwise
+come from the kernel. The test frame does use libc features, but the
+state machine code should be libc-free.
+
+- A lesser design goal is to completely describe the actions for each
+state transition in an sctp_command_t (see sctp_command.h). This
+means that the state functions (sctp_state_fn_t in sctp_sm.h) are NOT
+allowed to modify their endpoint, association, or chunk arguments.
+This is enforced by const modifiers--please respect the compiler
+warnings. All actions must be described in the last argument to the
+state function.
+
+- A byte order convention for dealing with the SCTP chunk headers:
+all SCTP chunks, regardless if the chunk is to be sent outbound
+to the network or was received inbound from the network, the header portion
+of the chunk is ALWAYS created and retained in the NETWORK BYTE ORDER.
+
+- An error code handling convention is to return negative values internally.
+The sk->err field holds a positive valued errno values, so will need our
+internal values negated.
+
+- We are moving toward an XP development model. So far we have
+adopted pair-programming, coding-to-test (functional and unit), design
+through refactoring, and story-based planning.
+
+In order to make XP work, it is very important that we have a complete
+set of tests for the code. We can not safely refactor major parts of
+the code without a way to find the things we break. If you decide to
+extend the SCTP Kernel Implementation we ask that you do the following:
+
+ 1) Pick an XP story. Tell lksctp-developers@lists.sourceforge.net
+ 2) Write a functional test for that XP story. The functional
+ test defines "DONE" for the story.
+ 3) Submit the functional test as a patch on SourceForge.
+ 4) Write unit tests for any new "objects" you define.
+ 5) Implement your feature.
+ 6) Submit the feature and the unit tests as a separate
+ SourceForge patch.
+
+Look in src/func_tests and in lksctp-tests package for examples of of tests.
+Please do not submit code that fails its own tests or any of the unit tests.
+If it fails a functional test, please document that with the submission.
+
+Another XP requirement is to code only what is you need to make the
+current test work. Where this means omitting required features, we
+have put in prominent BUG comments describing the omitted
+functionality.
+
+FEATURES
+--------
+This implementation uses a fairly compact cookie which is isolated in
+its own substructure of SCTP_association. We have been moving toward
+aggregating data elements which need to travel together to minimize
+copying of individual elements in favour of more efficient structure
+copies.
+
+You will find what we believe to be the smallest possible Internet
+simulator in the middle of the function test_kernel.c:simulate_internet().
+The simulator makes a few simplifying assumptions...
+
+MAILING LISTS and WEB SITES
+---------------------------
+http://www.sourceforge.net/projects/lksctp
+
+ This is the lksctp project webpage.
+
+linux-sctp@vger.kernel.org
+
+ This is the discussion list for developers. Join this list if
+ you are interested in following the day-to-day activities of
+ the SCTP Kernel Reference Implementation development community.
+ See subscription directions at:
+ http://vger.kernel.org/vger-lists.html#linux-sctp
+
+http://www.sctp.org
+
+ This is Randy Stewart's SCTP web site.
+
+http://sctp.de
+
+ This is Michael Tuexen's SCTP web site. Michael has collected
+ dozens of documents related to SCTP.
diff --git a/ROADMAP b/ROADMAP
new file mode 100644
index 0000000..0a65578
--- /dev/null
+++ b/ROADMAP
@@ -0,0 +1,45 @@
+TOUR
+----
+COPYING.lib Licensing terms of libsctp
+
+COPYING Licensing terms of other pieces of the package
+
+README Read this before developing.
+
+ChangeLog What has changed since the last release?
+
+AUTHORS Developers name list.
+
+INSTALL How to build and install this package.
+
+doc/ All the relevant Internet Drafts and RFC's.
+
+doc/states.txt This is a detailed state table for SCTP. It makes a
+ pretty good index for RFC2960 too...
+
+man/ SCTP man pages
+
+src/ Implementation of the user space library, include files -
+ this should go, some day, into glibc - as well as a set
+ of SCTP test tools and test programs.
+
+src/apps SCTP test applications.
+
+src/func_tests SCTP functional tests.
+
+src/lib Sources for SCTP library libsctp.a.
+
+src/testlib Sources for SCTP test library libsctputil.a.
+
+src/include/netinet
+ Header files needed for user space development.
+
+bin/ Scripts for lksctp build, installation and execution.
+
+test/ Testframe functional and unit tests. These tests use a
+ framework which enables running lksctp code in userspace.
+
+test/linux/include
+ This include heirarchy includes special versions of
+ kernel include files needed by the user-space test
+ frame.
diff --git a/bin/.gitignore b/bin/.gitignore
new file mode 100644
index 0000000..813925f
--- /dev/null
+++ b/bin/.gitignore
@@ -0,0 +1,5 @@
+compile
+depcomp
+install-sh
+ltmain.sh
+missing
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644
index 0000000..50985cb
--- /dev/null
+++ b/bin/Makefile.am
@@ -0,0 +1,8 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+noinst_SCRIPTS = aaaa
+
+EXTRA_DIST += $(noinst_SCRIPTS)
+
diff --git a/bin/aaaa b/bin/aaaa
new file mode 100755
index 0000000..f4982de
--- /dev/null
+++ b/bin/aaaa
@@ -0,0 +1,20 @@
+#! /bin/sh
+#
+# Run all the stuff we need to generate the configure and Makefile.in
+# in the automake process.
+#
+# The order needs to be that. If autoheader does not run after
+# autoconf, it doesn't get all the symbols right. As automake requires
+# config.h.in, created by autoheader, it needs to run after it.
+#
+# $Id: aaaa,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+
+
+set -ex
+
+aclocal
+autoconf
+autoheader
+# Set GNU strictness
+#automake --foreign
+automake --gnu
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..8d85a22
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+# -*- sh -*-
+set -ex # exit on error
+libtoolize --force --copy
+aclocal
+autoheader
+automake --foreign --add-missing --copy
+autoconf
+if [ "$1" = "-a" ]; then
+ ./configure --prefix=/usr --enable-shared --enable-static
+ make
+ make dist
+fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..5de5c76
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,133 @@
+dnl -*-autoconf-*-
+
+dnl lksctp-tools: Autoconf script
+dnl
+dnl $Id: configure.in,v 1.1.1.2 2002/08/06 23:55:45 inaky Exp $
+
+dnl (C) 2002 Intel Corporation
+dnl Iñaky Pérez-González <inaky.perez-gonzalez@intel.com>
+dnl - Initial packaging
+
+dnl Package info
+dnl (CONFIG_AUX_DIR is for putting stuff in $TOPSRCDIR/bin, so we
+dnl reduce clutter in the root; if we put it below AM_INIT_AUTOMAKE,
+dnl configure will fail ...)
+
+AC_INIT([lksctp-tools], [1.0.18], [], [], [http://www.lksctp.org/])
+AC_SUBST(LIBSCTP_CURRENT, 1)
+AC_SUBST(LIBSCTP_REVISION, 18)
+AC_SUBST(LIBSCTP_AGE, 0)
+AC_SUBST(LIBWITHSCTP_CURRENT, 1)
+AC_SUBST(LIBWITHSCTP_REVISION, 18)
+AC_SUBST(LIBWITHSCTP_AGE, 0)
+
+AC_CONFIG_AUX_DIR(bin)
+AC_CONFIG_SRCDIR([src/apps/sctp_darn.c])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_REVISION($Revision: 1.1.1.2 $)
+AM_INIT_AUTOMAKE
+m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
+AM_SILENT_RULES([yes])
+
+dnl Set defaults
+dnl CFLAGS="$CFLAGS -g -Wall"
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_ISC_POSIX
+
+dnl Checks for libraries.
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdint.h \
+ stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
+ sys/time.h unistd.h])
+AC_CHECK_HEADERS([linux/sctp.h], [], [], [AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_C_VOLATILE
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_SETVBUF_REVERSED
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([bzero gethostbyname gettimeofday memmove memset select socket \
+ strchr strerror strtol strtoul])
+
+# Support for stream reset even, added on v4.11, 35ea82d611da
+LKSCTP_CHECK_MEMBER([struct sctp_event_subscribe.sctp_stream_reset_event],
+ [HAVE_SCTP_STREAM_RESET_EVENT])
+
+# RFC 6525 (Stream Reconf), finished on v4.12, c0d8bab6ae51
+LKSCTP_CHECK_DECL([SCTP_RECONFIG_SUPPORTED], [HAVE_SCTP_STREAM_RECONFIG])
+
+# sctp_peeloff_flags was added on v4.13, 2cb5c8e378d1
+LKSCTP_CHECK_TYPE([sctp_peeloff_flags_arg_t], [HAVE_SCTP_PEELOFF_FLAGS])
+
+# New members to sctp_pdapi_event, added on v4.16, 65f5e357839e
+LKSCTP_CHECK_MEMBER([struct sctp_pdapi_event.pdapi_stream],
+ [HAVE_SCTP_PDAPI_EVENT_PDAPI_STREAM])
+LKSCTP_CHECK_MEMBER([struct sctp_pdapi_event.pdapi_seq],
+ [HAVE_SCTP_PDAPI_EVENT_PDAPI_SEQ])
+
+# PR-SCTP struct used to probe for sendv/recvv support, added on v4.17
+LKSCTP_CHECK_TYPE([struct sctp_prinfo], [HAVE_SCTP_SENDV])
+
+# This event indicates that the peer does not support SCTP authentication,
+# added on v4.16, 30f6ebf65bc4
+LKSCTP_CHECK_DECL([SCTP_AUTH_NO_AUTH], [HAVE_SCTP_AUTH_NO_AUTH])
+
+# New members to sctp_paddrparams, added on v4.19, 0b0dce7a36fb
+LKSCTP_CHECK_MEMBER([struct sctp_paddrparams.spp_ipv6_flowlabel],
+ [HAVE_SCTP_SPP_IPV6_FLOWLABEL])
+LKSCTP_CHECK_MEMBER([struct sctp_paddrparams.spp_dscp],
+ [HAVE_SCTP_SPP_DSCP])
+
+AC_CONFIG_HEADERS([src/include/netinet/sctp.h])
+AC_CONFIG_FILES([lksctp-tools.spec
+ Makefile
+ bin/Makefile
+ man/Makefile
+ src/Makefile
+ src/apps/Makefile
+ src/func_tests/Makefile
+ src/include/Makefile
+ src/include/netinet/Makefile
+ src/lib/Makefile
+ src/testlib/Makefile
+ src/withsctp/Makefile
+ doc/Makefile
+ libsctp.pc])
+
+# Build options
+AC_ARG_ENABLE(tests,
+ AS_HELP_STRING([--disable-tests],
+ [Build tests (default: yes)]),,
+ [enable_tests=yes])
+AM_CONDITIONAL(BUILD_TESTS, [test $enable_tests != no])
+
+AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..6ed32b8
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,12 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+internet_drafts = \
+ draft-stewart-tsvwg-sctpipv6-00.txt \
+ draft-stewart-tsvwg-sctpscore-01.txt
+
+rfcs = rfc2960.txt rfc3257.txt rfc3286.txt rfc3309.txt rfc3554.txt \
+ rfc3758.txt rfc3873.txt rfc4460.txt rfc4820.txt rfc4895.txt \
+ rfc4960.txt rfc5061.txt rfc5062.txt rfc6458.txt
+
+EXTRA_DIST += $(rfcs) $(internet_drafts)
diff --git a/doc/draft-stewart-tsvwg-sctpipv6-00.txt b/doc/draft-stewart-tsvwg-sctpipv6-00.txt
new file mode 100644
index 0000000..b89057d
--- /dev/null
+++ b/doc/draft-stewart-tsvwg-sctpipv6-00.txt
@@ -0,0 +1,161 @@
+Network Working Group R. R. Stewart
+INTERNET-DRA S. Deering
+ Cisco
+
+expires in six months June 1,2001
+
+
+
+ IPv6 addressing and Stream Control Transmission Protocol
+ <draft-stewart-tsvwg-sctpipv6-00>
+
+Status of This Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ Stream Control Transmission Protocol [RFC2960] provides transparent
+ multi-homing to its upper layer users. This multi-homing is
+ accomplished through the passing of address parameters in the
+ initial setup message used by SCTP. In an IPv4 network all addresses
+ are passed with no consideration for their scope and routeablility.
+ In a IPv6 network special considerations MUST be made to properly
+ bring up associations between SCTP endpoints that have IPv6
+ [RFC2460] addresses bound within their association. This document
+ defines those considerations and enumerates general rules
+ that an SCTP endpoint MUST use in formulating both the INIT and
+ INIT-ACK chunks.
+
+
+Table Of Contents
+
+
+
+
+1. Introduction
+
+
+ Stream Control Transmission Protocol [RFC2960] provides transparent
+ multi-homing to its upper layer users. This multi-homing is
+ accomplished through the passing of address parameters in the
+ initial setup message used by SCTP. In an IPv4 network all addresses
+ are passed with no consideration for their scope and routeablility.
+ In a IPv6 network special considerations MUST be made to properly
+ bring up associations between SCTP endpoints that have IPv6
+ [RFC2460] addresses bound within their association. This document
+ defines those considerations and enumerates general rules
+ that an SCTP endpoint MUST use in formulating both the INIT and
+ INIT-ACK chunks.
+
+ The emphasis in the rules laid out in this document are to prevent
+ an SCTP endpoint from listing an IPv6 address that is outside of its
+ routeable scope to a peer endpoint. This will prevent black-hole
+ conditions that may cause the unexpected failure of SCTP associations.
+
+2. Conventions
+
+ The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+ SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+ they appear in this document, are to be interpreted as described in
+ [RFC2119].
+
+3. Special rules for IPv6 address scoping
+
+ When selecting IPv6 addresses to include as parameters in the INIT
+ chunk the following rules MUST be applied:
+
+ A1) The INIT chunk SHOULD NOT include any IPv6 Link Local
+ address parameters unless the source or destination address
+ in the IPv6 header is a Link Local address.
+
+ A2) If IPv6 Link Local address parameters are included in the
+ INIT chunk, Link Local addresses that are NOT on the same
+ physical Link as that of the destination or source
+ IPv6 address (found in the IPv6 header) MUST NOT be included.
+
+ A3) The INIT chunk SHOULD NOT include any IPv6 Site Local
+ address parameters unless the source or destination address
+ in the IPv6 header is a Site Local address.
+
+ A4) If IPv6 Site Local addresses are included in the INIT chunk,
+ Site Local address that are NOT on the same site MUST NOT
+ be included.
+
+ A5) If the destination and source address of the INIT is an
+ IPv6 Global address then the sender SHOULD NOT include any
+ Site Local or Link Local IPv6 address parameters in the
+ INIT chunk.
+
+ When responding to an INIT chunk and selecting IPv6 address
+ parameters to be included in the INIT-ACK chunk, the following rules
+ MUST be applied:
+
+ B1) The INIT-ACK chunk SHOULD NOT include any IPv6 Link Local
+ address parameters unless the source or destination address
+ in the IPv6 header of the INIT chunk is a Link Local address.
+
+ B2) If IPv6 Link Local address parameters are included in the
+ INIT-ACK chunk, Link Local addresses that are NOT on the same
+ physical Link as the source or destination address in the
+ IPv6 header of the INIT chunk MUST NOT be included.
+
+ B3) The INIT-ACK chunk SHOULD NOT include any IPv6 Site Local
+ address parameters unless the source or destination address
+ in the IPv6 header of the INIT chunk is a Site Local address.
+
+ B4) If IPv6 Site Local addresses are included in the INIT-ACK
+ chunk, Site Local address that are NOT on the same site
+ as the received INIT chunk MUST NOT be included.
+
+ B5) If the destination and source address of the INIT is an
+ IPv6 Global address then the sender SHOULD NOT include any
+ Site Local or Link Local IPv6 address parameters in the
+ INIT-ACK chunk.
+
+4. Authors addresses
+
+
+ Randall R. Stewart
+ 24 Burning Bush Trail.
+ Crystal Lake, IL 60012
+ USA
+ Phone: +1 815 477 2127
+ EMail: rrs@cisco.com
+
+ Stephen E. Deering
+ Cisco Systems, Inc.
+ 170 West Tasman Drive
+ San Jose, CA 95134-1706
+ USA
+
+ Phone: +1 408 527 8213
+ Fax: +1 408 527 8254
+ EMail: deering@cisco.com
+
+
+5. References
+
+ [RFC2026] Bradner, S., "The Internet Standards Process -- Revision
+ 3", BCP 9, RFC 2026, October 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2460] S. Deering, R. Hinden, "Internet Protocol,
+ Version 6 (IPv6) Specification." December 1998.
+
+ [RFC2960] R. R. Stewart, Q. Xie, K. Morneault, C. Sharp,
+ H. J. Schwarzbauer, T. Taylor, I. Rytina, M. Kalla, L. Zhang,
+ and, V. Paxson, "Stream Control Transmission Protocol," RFC
+ 2960, October 2000.
diff --git a/doc/draft-stewart-tsvwg-sctpscore-01.txt b/doc/draft-stewart-tsvwg-sctpscore-01.txt
new file mode 100644
index 0000000..8cf31ab
--- /dev/null
+++ b/doc/draft-stewart-tsvwg-sctpscore-01.txt
@@ -0,0 +1,560 @@
+
+
+Network Working Group R. Stewart
+Internet-Draft Cisco Systems, Inc.
+Expires: November 30, 2003 M. Tuexen
+ Univ. of Applied Sciences Muenster
+ June 2003
+
+
+ Stream Control Transmission Protocol (SCTP) Bakeoff Scoring
+ draft-stewart-tsvwg-sctpscore-01.txt
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026.
+
+ Internet-Drafts are working documents of the Internet Engineering
+ Task Force (IETF), its areas, and its working groups. Note that
+ other groups may also distribute working documents as
+ Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at http://
+ www.ietf.org/ietf/1id-abstracts.txt.
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+ This Internet-Draft will expire on November 30, 2003.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+Abstract
+
+ This memo describes some of the scoring to be used in the testing of
+ Stream Control Transmission Protocol (SCTP) at upcoming bakeoffs.
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 1]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Base protocol . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2.1 Basic Communication . . . . . . . . . . . . . . . . . . . . . 3
+ 2.2 Beyond Basic Communication . . . . . . . . . . . . . . . . . . 4
+ 3. Protocol Extensions . . . . . . . . . . . . . . . . . . . . . 6
+ 3.1 Partial reliable SCTP . . . . . . . . . . . . . . . . . . . . 6
+ 3.2 AddIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 4. Bonus Points . . . . . . . . . . . . . . . . . . . . . . . . . 7
+ References . . . . . . . . . . . . . . . . . . . . . . . . . . 7
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 8
+ Intellectual Property and Copyright Statements . . . . . . . . 9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 2]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+1. Introduction
+
+ This document will be used as a basis for point scoring at upcoming
+ SCTP bakeoffs. Its purpose is similar to that described in RFC1025.
+ It is hoped that a clear definition of where and how to score points
+ will further the development of SCTP RFC2960 [4].
+
+ Note that while attending a bakeoff no one else will score your
+ points for you. We trust that all implementations will faithfully
+ record their points that are received honestly. Note also that these
+ scores are NOT to be used for marketing purposes. They are for the
+ use of the implementations to know how well they are doing. The only
+ reporting that will be done is a basic summary to the Transport Area
+ Working Group but please note that NO company or implementation names
+ will be attached.
+
+ Note Bene: Checksums must be enforced. No points will be awarded if
+ the checksum test is disabled.
+
+2. Base protocol
+
+ The base protocol is described in the follwing documents:
+
+ RFC2960 [4]
+
+ RFC3309 [5]
+
+ IMPLGUIDE [6]
+
+ SCTPIPV4 [9]
+
+ SCTPIPV6 [10]
+
+
+2.1 Basic Communication
+
+ These points will be scored for EACH peer implementation that you
+ successfully communicate with.
+
+ 2 points for being the sender of the INIT chunk and completing
+ setup of an association.
+
+ 2 points for being the sender of the INIT-ACK chunk and completing
+ setup of an association.
+
+ 1 point for sending data on the association where you sent the
+ INIT.
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 3]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+ 1 point for sending data on the association where you sent the
+ INIT-ACK.
+
+ 2 points for gracefully ending the conversation by being the
+ sender of the SHUTDOWN.
+
+ 2 points for gracefully ending the conversation by being the
+ sender of the SHUTDOWN-ACK.
+
+ 4 points for repeating the above without reinitializing the SCTP.
+
+ In order to receive all of the above points (14) an implementation
+ will need to:
+
+ o send a INIT chunk and setup an association.
+
+ o send a data chunk on that association.
+
+ o receive a data chunk on that association.
+
+ o send a SHUTDOWN chunk and bring the association to a close.
+
+ o receive a INIT-ACK and setup a new association (after the previous
+ one is closed).
+
+ o send a data chunk on that association.
+
+ o receive a data chunk on that association.
+
+ o receive a SHUTDOWN chunk and send a SHUTDOWN-ACK and close the
+ association.
+
+ o without restarting repeat these steps once.
+
+ You can get 5 extra points if you do not include any address
+ parameter in the INIT-/INIT-ACK chunk in case you are using ony one
+ of your addresses.
+
+2.2 Beyond Basic Communication
+
+ 10 points for bring up multiple associations at the same time to
+ different implementations. The implementation must send and
+ receive data on both associations simultaneously.
+
+ 15 points for correctly handling ECN.
+
+ 10 points for correctly handling both Transmission Sequence Number
+ (TSN) and Stream Sequence Number (SSN) wrap around.
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 4]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+ 5 points for correctly being able to process a "Kamikaze" packet
+ (AKA nastygram, christmas tree packet, lamp test segment, et al.).
+ That is, correctly handle a segment with the maximum combination
+ of features at once (e.g., a COOKIE-ECHO, SACK, ASCONF,
+ UNKNOWN-CHUNK, SHUTDOWN).
+
+ 5 additional points if the response to the "Kamikaze" packet is
+ bundled.
+
+ 10 additional points if the implementation supports ECN and thus
+ the "Kamikaze" packet is expanded to include COOKIE-ECHO, SACK,
+ ECN, ASCONF, UNKNOWN-CHUNK, SHUTDOWN.
+
+ 30 points for KOing your opponent with legal blows. (That is,
+ operate a connection until one SCTP or the other crashes, the
+ surviving SCTP has KOed the other. Legal blows are chunks that
+ meet the requirements of the specification.)
+
+ 20 points for KOing your opponent with dirty blows. (Dirty blows
+ are packets or chunks that violate the requirements of the
+ specification.)
+
+ 10 points for showing your opponents checksum is disabled or using
+ the old checksum aka Adler-32 RFC3309 [5].
+
+ 10 points for showing you can fast-retransmit.
+
+ 10 points for showing your t3-timer retransmits to an alternate
+ destination (aka uses the multi-homed facility during
+ retransmission).
+
+ 10 points for properly demonstrating the partial delivery API.
+
+ 10 points for demonstrating recognition and proper handling of
+ restart.
+
+ 10 points for correctly handling INIT collision.
+
+ 10 points for correctly handling the STALE COOKIE case (sending of
+ the error chunk).
+
+ 10 points an automatic resend of the INIT in case of a STALE
+ COOKIE with an appropiate COOKIE-PRESERVATIVE parameter such that
+ the association gets established.
+
+ 10 points for doing bulk transfer for over 10 Minutes at a high
+ constant rate.
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 5]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+ 5 points for handling the restart with a data transfer after that.
+
+ 10 points for proving that your opponent accepts additional
+ addresses during the restart compared to the original association.
+
+ 2 points for the correct handling of an unknown chunk with high
+ order bits 00, 01, 10, and 11. 2 additional points (10 in total)
+ for handling all four cases correctly.
+
+ 2 points for the correct handling of an unknown parameter with
+ high order bits 00, 01, 10, and 11. 2 additional points (10 in
+ total) for handling all four cases correctly.
+
+
+3. Protocol Extensions
+
+3.1 Partial reliable SCTP
+
+ This extension is currently being described in PRSCTP [8]
+
+ 10 points for sending a FWD-TSN to skip a "timed-out" data chunk.
+
+ 10 points for correctly adopting the new cumulative-ack point
+ indicated by a FWD-TSN.
+
+ 10 points for freeing data chunks to the application that were
+ held awaiting the FWD-TSN.
+
+ 10 points for properly handling the partial-delivery API where the
+ last part of a message already being delivered is subjected to a
+ FWD-TSN.
+
+
+3.2 AddIP
+
+ This extension is currently being described in ADDIP [7].
+
+ 10 points for adding an IP address to an existing association.
+
+ 10 points for deleting an IP address from an existing association.
+
+ 10 points for requesting that your peer set a primary address.
+
+ 10 points for showing that you honored the request to set a
+ primary address and thus adopted a new primary address.
+
+ 10 points for showing that your opponent does not do the address
+ scoping as described in SCTPIPV4 [9] and SCTPIPV6 [10] correctly.
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 6]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+4. Bonus Points
+
+ You can also Bonus Points (directly from RFC1025 [1] :>)
+
+ 10 points for the best excuse.
+
+ 20 points for the fewest excuses.
+
+ 30 points for the longest conversation.
+
+ 40 points for the most simultaneous connections.
+
+ 50 points for the most simultaneous connections with distinct
+ SCTPs.
+
+ 50 points for hijacking an existing association between other
+ participants.
+
+References
+
+ [1] Postel, J., "TCP and IP bake off", RFC 1025, September 1987.
+
+ [2] Bradner, S., "The Internet Standards Process -- Revision 3",
+ BCP 9, RFC 2026, October 1996.
+
+ [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [4] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+ [5] Stone, J., Stewart, R. and D. Otis, "Stream Control
+ Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+ September 2002.
+
+ [6] Stewart, R., Ong, L., Arias-Rodriguez, I., Poon, K., Conrad,
+ P., Caro, A. and M. Tuexen, "Stream Control Transmission
+ Protocol (SCTP) Implementer's Guide",
+ draft-ietf-tsvwg-sctpimpguide-08 (work in progress), March
+ 2003.
+
+ [7] Stewart, R., Ramalho, M., Xie, Q., Tuexen, M., Rytina, I.,
+ Belinchon, M. and P. Conrad, "Stream Control Transmission
+ Protocol (SCTP) Dynamic Address Reconfiguration",
+ draft-ietf-tsvwg-addip-sctp-07 (work in progress), February
+ 2003.
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 7]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+ [8] Stewart, R., Ramalho, M., Xie, Q., Tuexen, M. and P. Conrad,
+ "SCTP Partial Reliability Extension",
+ draft-stewart-tsvwg-prsctp-03 (work in progress), March 2003.
+
+ [9] Stewart, R. and M. Tuexen, "IPv4 Address handling for SCTP",
+ draft-stewart-tsvwg-sctpipv4-00 (work in progress), May 2002.
+
+ [10] Stewart, R. and S. Tuexen, "IPv6 addressing and Stream Control
+ Transmission Protocol", Internet-Draft
+ ddraft-stewart-tsvwg-sctpipv6-01, April 2002.
+
+
+Authors' Addresses
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 8725 West Higgins Road
+ Suite 300
+ Chicago, IL 60631
+ USA
+
+ Phone: +1-815-477-2127
+ EMail: rrs@cisco.com
+
+
+ Michael Tuexen
+ Univ. of Applied Sciences Muenster
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 8]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+Intellectual Property Statement
+
+ The IETF takes no position regarding the validity or scope of any
+ intellectual property or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; neither does it represent that it
+ has made any effort to identify any such rights. Information on the
+ IETF's procedures with respect to rights in standards-track and
+ standards-related documentation can be found in BCP-11. Copies of
+ claims of rights made available for publication and any assurances of
+ licenses to be made available, or the result of an attempt made to
+ obtain a general license or permission for the use of such
+ proprietary rights by implementors or users of this specification can
+ be obtained from the IETF Secretariat.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights which may cover technology that may be required to practice
+ this standard. Please address the information to the IETF Executive
+ Director.
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assignees.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 9]
+
+Internet-Draft Bakeoff Scoring June 2003
+
+
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart & Tuexen Expires November 30, 2003 [Page 10]
+
diff --git a/doc/ols.sty b/doc/ols.sty
new file mode 100644
index 0000000..5e5fe49
--- /dev/null
+++ b/doc/ols.sty
@@ -0,0 +1,56 @@
+
+% TEMPLATE for Usenix papers, specifically to meet requirements of
+% TCL97 committee.
+% originally a template for producing IEEE-format articles using LaTeX.
+% written by Matthew Ward, CS Department, Worcester Polytechnic Institute.
+% adapted by David Beazley for his excellent SWIG paper in Proceedings,
+% Tcl 96
+% turned into a smartass generic template by De Clarke, with thanks to
+% both the above pioneers
+% use at your own risk. Complaints to /dev/null.
+% make it two column with no page numbering, default is 10 point
+
+% adapted for Ottawa Linux Symposium
+
+% include following in document.
+%\documentclass[twocolumn]{article}
+%\usepackage{usits,epsfig}
+\pagestyle{empty}
+
+%set dimensions of columns, gap between columns, and space between paragraphs
+%\setlength{\textheight}{8.75in}
+\setlength{\textheight}{9.0in}
+\setlength{\columnsep}{0.25in}
+\setlength{\textwidth}{6.45in}
+\setlength{\footskip}{0.0in}
+\setlength{\topmargin}{0.0in}
+\setlength{\headheight}{0.0in}
+\setlength{\headsep}{0.0in}
+\setlength{\oddsidemargin}{0in}
+%\setlength{\oddsidemargin}{-.065in}
+%\setlength{\oddsidemargin}{-.17in}
+\setlength{\parindent}{0pc}
+\setlength{\parskip}{\baselineskip}
+
+% started out with art10.sty and modified params to conform to IEEE format
+% further mods to conform to Usenix standard
+
+\makeatletter
+%as Latex considers descenders in its calculation of interline spacing,
+%to get 12 point spacing for normalsize text, must set it to 10 points
+\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt
+\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip
+\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt
+minus3pt\let\@listi\@listI}
+
+%need a 12 pt font size for subsection and abstract headings
+\def\subsize{\@setsize\subsize{12pt}\xipt\@xipt}
+
+%make section titles bold and 12 point, 2 blank lines before, 1 after
+\def\section{\@startsection {section}{1}{\z@}{24pt plus 2pt minus 2pt}
+{12pt plus 2pt minus 2pt}{\large\bf}}
+
+%make subsection titles bold and 11 point, 1 blank line before, 1 after
+\def\subsection{\@startsection {subsection}{2}{\z@}{12pt plus 2pt minus 2pt}
+{12pt plus 2pt minus 2pt}{\subsize\bf}}
+\makeatother
diff --git a/doc/ols.tex b/doc/ols.tex
new file mode 100644
index 0000000..1e47606
--- /dev/null
+++ b/doc/ols.tex
@@ -0,0 +1,720 @@
+% TEMPLATE for Usenix papers, specifically to meet requirements of
+% TCL97 committee.
+% originally a template for producing IEEE-format articles using LaTeX.
+% written by Matthew Ward, CS Department, Worcester Polytechnic Institute.
+% adapted by David Beazley for his excellent SWIG paper in Proceedings,
+% Tcl 96
+% turned into a smartass generic template by De Clarke, with thanks to
+% both the above pioneers
+% use at your own risk. Complaints to /dev/null.
+% make it two column with no page numbering, default is 10 point
+
+% Munged by Fred Douglis <douglis@research.att.com> 10/97 to separate
+% the .sty file from the LaTeX source template, so that people can
+% more easily include the .sty file into an existing document. Also
+% changed to more closely follow the style guidelines as represented
+% by the Word sample file.
+% This version uses the latex2e styles, not the very ancient 2.09 stuff.
+
+% adapted for Ottawa Linux Symposium
+
+\documentclass[twocolumn]{article}
+\usepackage{ols,epsfig}
+\begin{document}
+
+%Remove this next line if your system defaults correctly.
+\special{papersize=8.5in,11in}
+
+%don't want date printed
+\date{}
+
+%make title bold and 14 pt font (Latex default is non-bold, 16 pt)
+\title{\Large \bf Linux Kernel SCTP : The Third Transport}
+
+%for single author (just remove % characters)
+\author{
+La~Monte H.P.\ Yarroll \\
+%{\em Your Department} \\
+{\em Motorola GTSS}\\
+%{\em Your City, State, ZIP}\\
+% is there a standard format for email/URLs??
+% remember that ~ doesn't do what you expect, use \~{}.
+{\normalsize piggy@acm.org} \\
+%
+% copy the following lines to add more authors
+\and
+Karl Knutson \\
+{\em Motorola GTSS}\\
+%% is there a standard format for email/URLs??
+{\normalsize karl@athena.chicago.il.us}
+%
+} % end author
+
+\maketitle
+
+% You have to do this to suppress page numbers. Don't ask.
+\thispagestyle{empty}
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+
+\subsection*{Abstract}
+% nuked italics -- FD
+
+The Stream Control Transmission Protocol (SCTP) is a reliable
+message-oriented protocol with transparent support for multihoming.
+It allows multiple independent complex exchanges which all share a
+single connection and congestion context.
+
+We provide an overview of the protocol, the UDP-style API and the
+details of the Linux kernel reference implementation. The brief API
+discussion is intended for developers wishing to use SCTP. The
+detailed implementation discussion is for developers interested in
+contributing to the kernel development effort.
+
+\section{Introduction}
+
+The developers at the Linux 2.5 Kernel Summit in San Jose achieved a
+rough consensus that 2.5 should probably support SCTP, a new transport
+protocol from the IETF. This paper introduces the ongoing work on
+such an implementation, providing some details for both the
+application developer and the kernel developer.
+
+The Stream Control Transmission Protocol (SCTP) is a reliable
+message-oriented protocol with transparent support for multihoming.
+It allows multiple independent complex exchanges which all share a
+single connection and congestion context.
+
+\subsection{History of SCTP}
+The SIGTRAN (Signalling Transport) Working Group of the IETF is
+concerned with the transport of telephony signalling data over IP.
+Upon reviewing the available standard transport protocols, they
+concluded that none of them met the transport requirements of
+signalling data.
+
+SIGTRAN concluded that they needed a new transport protocol which
+could provide reliable message delivery, tolerate network failures,
+and avoid the head-of-line-blocking problem. We will discuss this
+problem later.
+
+The WG selected a proposal from Randall Stewart and Qiaobing Xie of
+Motorola as a starting point. Stewart and Xie had developed a
+Distributed Processing Environment, Quantix, aimed at telephony
+applications. This DPE had been successfully demonstrated at Geneva
+Telecom in 1999.
+
+The Working Group took great care in constructing the new protocol,
+SCTP, incorporating many lessons learned from TCP, such as congestion
+control, selective ACK, message fragmentation and bundling.
+
+The core transport protocol from Quantix brought support for
+multihoming, message framing, and streams. We discuss all of these
+features at length later.
+
+The IESG decided that the resulting protocol was robust enough to be
+elevated from a specialised transport for telephony signalling to a new
+general purpose transport to stand beside UDP and TCP. To this end,
+they moved the work from SIGTRAN to TSVWG, the general transport
+group.
+
+As of this writing, the core specification, \cite{rfc2960}, is at Proposed
+Standard. There have been three successful bakeoffs covering over 25
+separate implementations. Lessons learned from the most recent
+bakeoff are being written up in an ``Implementor's Guide'', \cite{impl}.
+
+\subsection{SCTP in the Linux kernel}
+
+Shortly before the first bakeoff, the IESG asked SIGTRAN to move SCTP
+from riding on UDP to riding directly on top of IP. The long term
+goal was clearly was to move SCTP from user space into the kernel.
+
+Aside from the obvious performance gains, this has the effect of
+reducing the number of implementations to roughly one per operating
+system. This makes it easier to verify the stability of most of the
+implementations which appear on the Internet.
+
+Randall Stewart saw the importance of this and started one of the
+authors of this paper working on a port of the user space
+implementation to the Linux kernel. This port was intended as a
+reference for developers of implementations for other kernels to
+examine. The Linux kernel implementation has since diverged
+significantly from the user space reference, but maintains the
+standards of a reference implementation (see Coding Standards, below).
+
+\subsection{SCTP examples}
+
+SCTP is a reliable message-oriented protocol with transparent support
+for multihoming. It allows multiple independent complex exchanges
+which all share a single connection and congestion context.
+
+Many network applications operate by exchanging simultaneously, short,
+similar sequences of data continuously. The traffic produced by these
+operations can be characterised as MICE (Multiple Independent Complex
+Exchanges). It is also true that many applications which use MICE
+also have high network reliability requirements.
+
+\subsubsection{A database app}
+One example is a client/server database application. Each request and
+each response is a message. Each transaction is a sequence of
+dependent request/response pairs.
+
+Implemented over TCP, this application would have to provide its own
+message boundaries, since TCP sends bytes, not messages. How do we
+implement MICE with TCP? We have two ways of doing this: multiple
+connections, or a single multiplexed and reused connection.
+
+With each transaction over a separate TCP connection, we gain the
+independence of transactions, but at a cost in performance. Since TCP
+(as a general purpose transport protocol) uses congestion control,
+each of the connections would have to go through slow-start and if
+most transactions were short, they would never get out of slow-start.
+
+With all transactions over a single TCP connection, we make efficient
+use of the network bandwidth, but open ourselves up to the
+head-of-line blocking problem. This means that if one segment in one
+transaction is lost, this blocks all transactions, not just the one
+with the lost segment.
+
+If we use SCTP for the same application we gain the benefits of using
+TCP, as well as advantages peculiar to SCTP. SCTP directly supports
+messages and guarantees TCP-like levels of bandwidth efficiency via
+bundling and fragmentation. Each database transaction can be
+represented as an ordered stream of messages, which are independent in
+SCTP for retransmission purposes. This means that while SCTP has the
+same congestion control mechanisms as TCP, it does not have to resort
+to multiple connections nor is it vulnerable to the head-of-line
+blocking problem.
+
+\subsubsection{A free clinic}
+
+Another example of SCTP use is for a free\footnote{Free as in ``free
+beer''.} clinic which needs a reliable way to use its IP-networked
+patient monitoring software.
+
+This has many similarities to the example above in that different
+monitoring devices would need to send simultaneous
+information---multiple independent complex exchanges. The main
+difference is in the higher network reliability requirements.
+
+A reasonable way to improve the network reliability is to set up a
+parallel network and use multihoming for the client and server
+applications. However, if the application is TCP-based, the
+multihoming needs to be added to the application. With SCTP, the
+multihoming ability is built into the protocol. All that is necessary
+is to make the appropriate socket calls and SCTP will take advantage
+of the addresses available in the existing network. This also applies
+if one side of the connection has more addresses than the other.
+
+\section{The UDP-style API}
+
+Any new protocol needs an API. In particular for an Internet
+protocol, it's important to have the API match the API normally used
+for IP networks. This is the Berkeley sockets model---the SCTP
+version is defined in the Internet Draft ``Sockets API Extensions for
+SCTP''\cite{api}. The API draft defines two complementary interfaces
+to SCTP--one for compatibility with older TCP-based applications, and
+another for new applications designed expressly to use SCTP. The
+Linux Kernel SCTP stack does not yet implement the former, so we
+discuss only the UDP-style interface.
+
+The conceptual model of the UDP-style API is (naturally) that of plain
+UDP. To send a message in UDP, you create a socket, bind an address
+to it and send your message using \texttt{sendmsg()}. To receive a
+message in UDP, you create a socket, bind an address to it and use
+\texttt{recvmsg()}. It's much the same with the UDP-style API for
+SCTP. To send a message, you create a socket, bind \textit{addresses}
+to it and use \texttt{sendmsg()}. The SCTP stack underlying the API
+handles association startup and shutdown automatically. The same goes
+for message reception. To receive a message in UDP-style, you create
+a socket, bind \textit{addresses} to it and use \texttt{recvmsg()}.
+
+The important API differences between UDP and UDP-style SCTP are:
+multihoming; ancillary data; and the option of notifications from the
+SCTP stack.
+
+\subsection{Multihoming and \texttt{bindx()}}
+
+There are three ways to work with multihoming with SCTP. One is to
+ignore multihoming and use one address. Another way is to bind all
+your addresses through the use of \texttt{INADDR\_ANY} or
+\texttt{IN6ADDR\_ANY}. This will ``associate the endpoint with the
+optimal subset of available local interfaces.''(Section 3.1.2,
+\cite{api}) The most flexible way is through the use of
+\texttt{sctp\_bindx()}, which allows additional addresses to be
+added to a socket after the first one is bound with \texttt{bind()},
+but before the socket is used to transfer or receive data. The
+function \texttt{sctp\_bindx()} is further described in section 8.1 of
+\cite{api}.
+
+\subsection{Ancillary data}
+
+To use streams with the UDP-style API, you use ancillary data in the
+\texttt{struct~cmsghdr} part of the \texttt{struct~msghdr} argument to
+both \texttt{sendmsg()} and \texttt{recvmsg()}. Ancillary data is
+used for initialisation data (\texttt{struct~sctp\_initmsg} and for
+header data (\texttt{struct~sctp\_sndrcvinfo}).
+
+Ancillary data are manipulated with the macros \texttt{CMSG\_FIRSTHDR,
+CMSG\_NEXTHDR, CMSG\_DATA, CMSG\_SPACE, \textnormal{and} CMSG\_LEN}.
+These are all defined in \cite{rfc2292}. \cite{api} provides a nice
+example in section 5.4.2.
+
+{\tt \small
+\begin{verbatim}
+ struct sctp_initmsg {
+ uint16_t sinit_num_ostreams;
+ uint16_t sinit_max_instreams;
+ uint16_t sinit_max_attempts;
+ uint16_t sinit_max_init_timeo;
+ };
+\end{verbatim}
+}
+
+The initialisation ancillary data sets information for starting
+new associations.
+
+{\tt \small
+\begin{verbatim}
+ struct sctp_sndrcvinfo {
+ uint16_t sinfo_stream;
+ uint16_t sinfo_ssn;
+ uint16_t sinfo_flags;
+ uint32_t sinfo_ppid;
+ uint32_t sinfo_context;
+ uint8_t sinfo_dscp;
+ sctp_assoc_t sinfo_assoc_id;
+ };
+\end{verbatim}
+}
+
+The header ancillary data reports information gleaned from the SCTP
+headers. If requested with the \texttt{SCTP\_RECVDATAIOEVNT} socket
+option, this ancillary data is provided with every inbound data
+message. There is a handy key (\texttt{sinfo\_assoc\_id}) which
+identifies the association for this particular message. It also
+provides the flags needed to implement partial delivery of very large
+messages.
+
+Outbound messages should include an \texttt{sctp\_sndrcvinfo} ancillary
+data structure to tell SCTP which SCTP stream to put this datagram
+into. It is also possible to set a default stream so that this
+ancillary data may be omitted.
+
+\subsection{Notifications}
+
+SCTP provides for the concept of optional notifications. These are
+messages delivered in-band about events inside the SCTP stack, such as
+a destination transport address failure or a new association coming
+up. The notifications are marked with the \texttt{MSG\_NOTIFICATION}
+flag in the \texttt{msg\_flags} field of the \texttt{sctp\_sendrcvinfo}
+ancillary data. The notification is delivered as the body of the
+message returned by \texttt{recvmsg()}.
+
+In \ref{notifications} we find a table of notifications. Each
+notification delivers its own data structure which shares the same
+name (lower case, naturally) as the notification type itself. The first
+field of every notification is a \texttt{uint16\_t} which caries the
+notification type.
+
+\begin{figure*}[t]
+\begin{center}
+{\tt
+\begin{tabular}{ l l l }
+ \hline
+ \textnormal{Type} & \textnormal{Socket Option} & \textnormal{Description} \\
+ \hline
+ SCTP\_ASSOC\_CHANGE & SCTP\_RECVASSOCEVNT & \textnormal{Change of association} \\
+ SCTP\_PEER\_ADDR\_CHANGE & SCTP\_RECVADDREVNT & \textnormal{Change in status of a given address} \\
+ SCTP\_REMOTE\_ERROR & SCTP\_RECVPEERERR & \textnormal{An error received from a peer} \\
+ SCTP\_SEND\_FAILED & SCTP\_RECVSENDFAILEVNT & \textnormal{A failure to send} \\
+ SCTP\_SHUTDOWN\_EVENT & SCTP\_RECVDOWNEVNT & \textnormal{The reception of a \texttt{SHUTDOWN} chunk} \\
+\end{tabular}
+}
+\end{center}
+\caption{\label{notification}Useful notifications for an SCTP socket}
+\end{figure*}
+
+\section{The lksctp Project}
+
+A critical factor in the success of any new IETF protocol is of course
+a Linux implementation. Fortunately, key personnel at Motorola
+recognised this and encouraged us to tackle such a project. Months
+later, we have a core implementation with an ever-expanding feature
+set. We now have significant participation from developers at IBM and
+Intel and the pace is picking up.
+
+\subsection{Coding standards}
+
+In addition to the usual requirements of kernel code, our code seeks
+to be a useful reference for people making their own kernel
+implementations of SCTP. If a reader has some question about how to
+implement a particular section of the RFC, they need only grep for the
+relevant text in our code and they can find an example. As much as
+practical, we draw names directly from the RFC. We made the state
+machine into an explicit table (see \ref{states} for an
+excerpt) with names that refer directly back to the relevant section
+numbers. Clarity is a compelling requirement for our code.
+
+\subsection{Extreme Programming}
+
+As the project grew and we added developers, we clearly needed some
+way of coordinating our work. We decided to experiment with Extreme
+Programming, \cite{xp}.
+
+XP is a collection of practices aimed at controlling risk in a small
+to medium-sized software development project. One important principle
+is that you should do the simplest thing that could possibly work. A
+second important principle is to take advantage of the fact that
+programmers like to code.
+
+We use a range of XP practices, but the practices which are most
+visible to anybody who reads or works on lksctp are the tests and the
+metaphors.
+
+\section{The Tests}
+
+One of the XP practices we use is code-to-the-test. XP asks, ``If
+testing is good, why don't we do it all the time?'' Instead of writing
+tests for working code, write tests first, and then write code to pass
+the tests. This practice leads to a large automated test suite which
+runs several times per day.
+
+We use three kinds of test, unit tests, test frame functional tests,
+and live kernel functional tests.
+
+The most basic form of test is the unit test. Unit tests exercise all
+the interfaces of a particular object and confirm that it behaves
+correctly. They also encode regression checks for fixed bugs. These
+tests all have names beginning with \texttt{test\_}.
+
+The second form of test is the test frame functional tests. These are
+the tests with names beginning with \texttt{ft\_frame\_}. These tests
+check for external behaviours of the system, but with a simulated
+kernel. The simulated kernel is very light weight and gives us very
+fine control over things like timing and network properties.
+
+Ideally, functional tests should be written by the customer for a
+system---they encode the behaviours that the customer expects. In our
+case, we play the role of customer on behalf of the RFC. We also use
+test frame functional tests to define work items for off-site
+development groups. The off-site group writes tests which describe the
+feature they intend to implement and submits those tests as a
+proposal. This has proven an excellent medium for describing work.
+
+The final form of test we use is the live kernel functional test. We
+have many fewer of these than we would like---they are difficult to run
+since we must install and boot a kernel to test. This is much more
+work than simply running \texttt{make unit\_test}. We are exploring UML as
+a possible way to automate our kernel functional tests. These tests
+have names beginning with \texttt{ft\_kern\_}.
+
+Code-to-the-test is a practice which you can introduce at any point in
+a project. When you first start, it seems that you are spending more
+time writing tests than writing code, but once you begin to have a
+critical mass of interacting tests you begin to see significant
+payoffs in both code quality and development velocity.
+
+We have had several incidents where interactions between unit tests
+and functional tests have uncovered complimentary masking bugs.
+
+Tests are not a substitute for understanding code---they are a
+mechanism for encoding that understanding to share with other
+developers, including future versions of yourself. You can learn
+nearly as much about our code by reading our tests as by reading the
+code itself.
+
+Lately, we have begun using functional tests to encode major bugs.
+These are among the best of all possible bug reports---they describe
+the failure precisely and tell exactly when the problem is gone.
+After the bugs are fixed the tests serve as part of the regression
+suite.
+
+\section{The Metaphors}
+
+XP projects are built around a unifying metaphor rather than an
+elaborate architecture. In our case, we chose two metaphors which
+could serve quite well for nearly any protocol development project.
+
+Our metaphors are the state machine and the smart pipe. Most readers
+are probably familiar with the state machine, but the smart pipe is a
+twist on a familiar concept. The idea behind a smart pipe\footnote{An
+alternate term may be ``oven''.} is that raw stuff goes in one end and
+cooked stuff comes out the other end.
+
+\subsection{The State Machine}
+
+The state machine in our implementation is quite literal. We have an
+explicit state table which keys to specific state functions which are
+tied directly back to parts of the RFC. The core of the state machine
+(found in \texttt{sctp\_do\_sm()}) is almost purely functional---only header
+conversions are permitted. Each state function produces a description
+of the side effects (in the form of a \texttt{struct~sctp\_sm\_retval})
+needed to handle the particular event. A separate side effect
+processor, \texttt{sctp\_side\_effects()}, converts this structure into
+actions.
+
+Events fall into four categories. The RFC is very explicit about
+state transitions associated with arriving chunks. The RFC discusses
+transitions due to primitive requests from upper layers, but many of
+these are implementation dependent. The third category of events is
+timeouts. The final category is a catch-all for odd events like
+queues emptying.
+
+\begin{figure*}[t]
+\begin{center}
+{\tt
+\begin{tabular}{ l l l l l }
+ \hline
+ \textnormal{State:} & CLOSED & COOKIE-WAIT & COOKIE-ECHOED & ESTABLISHED \\
+ \hline
+ \hline
+ \textnormal{Chunks} & & & & \\
+ \hline
+
+ INIT & do\_5\_1B\_init & do\_5\_2\_1\_siminit & do\_5\_2\_1\_siminit & do\_5\_2\_2\_dupinit \\
+ INIT ACK & discard(5.2.3) & do\_5\_1C\_ack & discard(5.2.3) & discard(5.2.3) \\
+ COOKIE ECHO & do\_5\_1D\_ce & do\_5\_2\_4\_dupcook& do\_5\_2\_4\_dupcook& do\_5\_2\_4\_dupcook \\
+ COOKIE ACK & discard & discard(5.2.5) & do\_5\_1E\_ca & discard(5.2.5) \\
+ DATA & tabort\_8\_4\_8 & discard(6.0) & discard(6.0) & eat\_data\_6\_2 \\
+ SACK & tabort\_8\_4\_8 & discard(6.0) & eat\_sack\_6\_2\_1 & eat\_sack\_6\_2\_1 \\
+
+ \hline
+ \textnormal{Timeouts} & & & & \\
+ \hline
+
+ T1-INIT TO & bug & do\_4\_2\_reinit & bug & bug \\
+ T3-RTX TO & bug & bug & do\_6\_3\_3\_retx & do\_6\_3\_3\_retx \\
+
+ \hline
+ \textnormal{Primitives} & & & & \\
+ \hline
+
+ PRM\_ASSOCIATE & do\_PRM\_ASOC & error & error & error \\
+ PRM\_SEND & error & do\_PRM\_SENDQ6.0 & do\_PRM\_SENDQ6.0 & do\_PRM\_SEND \\
+
+\end{tabular}
+}
+\end{center}
+\caption{\label{states}Portion of SCTP state table showing association initialisation}
+\end{figure*}
+
+In order to create an explicit state machine, it was necessary to
+first create an explicit state table. The process of creating this
+table uncovered a few minor contradictions in one of the drafts of the
+RFC. These mostly involved conflicting catch-all cases. In Figure 1
+we have an excerpt which shows the state functions involved in
+initialising a new association.
+
+\subsection{The Smart Pipes}
+
+Each smart pipe has one or more structures which define its internal
+data, and a set of functions which define its external interactions.
+In this respect these smart pipes can be considered a type of object,
+in the OO sense. All of these definitions can be found in the include
+file \texttt{<net/sctp/sctpStructs.h>}.
+
+Most of our smart pipes have push inputs---external objects explictly
+put things in by calling methods directly. A pull input is
+possible---the smart pipe would need to have a way to register a
+callback function which can fetch more input in response to some other
+stimulus.
+
+Some of our pipes use pull outputs. E.g. \texttt{SCTP\_ULPqueue} passes
+data and notifications up the protocol stack through explicit calls to
+the socket functions, usually \texttt{readmsg(2)}. Some of our smart
+pipes use push outputs. E.g. \texttt{SCTP\_outqueue} has a set of
+callback functions which it invokes when it needs to send chunks out
+toward the wire.
+
+There are four smart pipes in lksctp. They are
+\texttt{SCTP\_inqueue}, \texttt{SCTP\_ULPqueue},
+\texttt{SCTP\_outqueue}, and \texttt{SCTP\_packet}. The first two
+carry information up the stack from the wire to the user; the second
+two carry information back down the stack.
+
+\subsubsection{\texttt{SCTP\_inqueue}}
+
+\texttt{SCTP\_inqueue} accepts packets and provides chunks. It is
+responsible for reassembling fragments, unbundling, tracking received
+TSN's for acknowledgement, and managing rwnd for congestion control.
+There is an \texttt{SCTP\_inqueue} for each endpoint (to handle chunks
+not related to a specific association) and one for each association.
+
+The function \texttt{sctp\_v4\_rcv()} (which is the receiving function
+for SCTP registered with IPv4) calls \texttt{sctp\_push\_inqueue()} to
+push packets into the input queue for the appropriate association or
+endpoint. The function \texttt{sctp\_push\_inqueue()} schedules
+either \texttt{sctp\_bh\_rcv\_asoc()} or \texttt{sctp\_bh\_rcv\_ep()}
+on the immediate queue to complete delivery. These functions call
+\texttt{sctp\_pop\_inqueue()} to pull data out of the
+\texttt{SCTP\_inqueue}. This function does most of the work for this
+smart pipe.
+
+The functions \texttt{sctp\_bh\_rcv\_ep()} and
+\texttt{sctp\_bh\_rcv\_asoc()} run the state machine on incoming
+chunks. Among many other side effects, the state machine can generate
+events for an upper-layer-protocol (ULP), and/or chunks to go back out
+on the wire.
+
+\subsubsection{\texttt{SCTP\_ULPqueue}}
+
+\texttt{SCTP\_ULPqueue} is the smart pipe which accepts events (either
+user data messages or notifications) from the state machine and
+delivers them to the ULP through the sockets layer. It is responsible
+for delivering streams of messages in order. There is one
+\texttt{SCTP\_ULPqueue} for every endpoint, but this is likely to
+change at some point to one \texttt{SCTP\_ULPqueue} for each socket.
+This smart pipe uses a data structure distributed between the
+\texttt{struct~SCTP\_endpoint} and the
+\texttt{struct~SCTP\_association}.
+
+The state machine, \texttt{sctp\_do\_sm()}, pushes data into an
+\texttt{SCTP\_ULPqueue} by calling
+\texttt{sctp\_push\_chunk\_ULPqueue()}. It pushes notifications with
+\texttt{sctp\_push\_event\_ULPqueue()}. The sockets layer extracts
+events from an \texttt{SCTP\_ULPqueue} with
+\texttt{sctp\_pop\_ULPqueue()}.
+
+\subsubsection{\texttt{SCTP\_outqueue}}
+
+\texttt{SCTP\_outqueue} is responsible for bundling logic, transport
+selection, outbound congestion control, fragmentation, and any
+necessary data queueing. It knows whether or not data can go out onto
+the wire yet. With one exception noted below, every outbound chunk
+goes through an \texttt{SCTP\_outqueue} attached to an association.
+The state machine injects chunks into an \texttt{SCTP\_outqueue} with
+\texttt{sctp\_push\_outqueue()}. They automatically push out the other
+end through a small set of callbacks which are normally attached to an
+\texttt{SCTP\_packet}.
+
+The state machine is capable of putting a fully-formed packet directly
+on the wire. At this point only \texttt{ABORT} uses this feature. It is
+likely that we will refactor \texttt{INIT ACK} generation again to use
+this feature.
+
+\subsubsection{\texttt{SCTP\_packet}}
+
+An \texttt{SCTP\_packet} is a lazy packet transmitter associated with a
+specific transport. The upper layer pushes data into the packet,
+usually with \texttt{sctp\_transmit\_chunk()}. The packet blindly
+bundles the chunks. If the it fills (hits the PMTU for its transport),
+it transmits the packet to make room for the new chunk.
+\texttt{SCTP\_packet} rejects packets which need fragmenting. It is
+possible to force a packet to transmit immediately with
+\texttt{sctp\_transmit\_packet()}. \texttt{SCTP\_packet} tracks the
+congestion counters, but handles none of the congestion logic.
+
+\section{More Data Structures}
+
+Not everything is a state table or a smart pipe---after all, this is
+the kernel and we ARE programming in C. Here again, we have followed
+the RFC very closely. Most of the key concepts in the RFC manifest
+themselves as explicit data structures. For convenience, we refer to
+these data structures as ``nouns''.
+
+Nearly all of the ``noun'' structures are designed for use with the
+\texttt{sk\_buff} macros for list manipulation. These macros provide a
+doubly-linked list with locking.
+
+\subsection{\texttt{struct~SCTP\_proto}}
+
+The entire lksctp universe is grounded in an instance of \texttt{
+struct~SCTP\_proto} accessible through \texttt{sctp\_get\_protocol()}.
+This structure holds system-wide defaults for things like the maximum
+number of permitted retransmissions. It contains a list of all
+endpoints on the system.
+
+\subsection{\texttt{struct~SCTP\_endpoint}}
+
+Each UDP-style SCTP socket has an endpoint, represented as a
+\texttt{struct~SCTP\_endpoint}. Once we implement high-bandwidth sockets and
+TCP-style sockets, it will be possible for multiple sockets to share a
+single endpoint structure. The endpoint structure contains a local
+SCTP socket number and a list of local IP addresses. These two items
+define the endpoint uniquely. In addition to endpoint-wide default
+values and statistics, the endpoint maintains a list of associations.
+
+\subsection{\texttt{struct~SCTP\_association}}
+
+Each association structure, \texttt{struct~SCTP\_association}) is defined
+by a local endpoint (a pointer to a \texttt{struct~SCTP\_endpoint}), and
+a remote endpoint (an SCTP port number and a list of transport
+addresses). This is one of the most complicated structures in the
+implementation as it includes a great deal of information mandated by
+the RFC. Among many other things, this structure holds the state of
+the state machine. The list of transport addresses for the remote
+endpoint is more elaborate than the simple list of IP addresses in the
+local endpoint data structure since SCTP needs to maintain congestion
+information about each of the remote transport addresses.
+
+\subsection{\texttt{struct~SCTP\_transport}}
+
+A \texttt{struct~SCTP\_transport} is defined by a remote SCTP port number
+and an IP address. The structure holds congestion and reachability
+information for the given address. This is also where we get the list
+of functions to call to manipulate the specific address family. For
+TCP you would find this information way up in the socket, but this is
+not possible for SCTP.
+
+\subsection{\texttt{struct~SCTP\_chunk}}
+
+Possibly the most fundamental data structure in lksctp is
+\texttt{struct~SCTP\_chunk}. This holds SCTP chunks both inbound and
+outbound. It is essentially an extension to \texttt{struct~sk\_buff}.
+It adds pointers to the various possible SCTP subheaders and a few
+flags needed specifically for SCTP. One strict convention is that
+\texttt{chunk->skb->data} is the demarcation line between headers in
+network byte order and headers in host byte order. All outbound
+chunks are ALWAYS in network byte order. The first function which
+needs a field from an inbound chunk converts that full header to host
+byte order {\it in situ}.
+
+\section{Acknowledgements}
+
+The authors are members of a team at Motorola dedicated to producing
+open source implementations in support of IETF standardisation. We
+would like to thank the people who make these efforts possible,
+specifically Maureen~Govern, Stephen~Spear, Qiaobing~Xie, and
+Irfan~Ali. We are of course deeply indebted to Randall Stewart and
+Qiaobing Xie for having created SCTP and for starting the Linux Kernel
+SCTP Implementation Project. We wish to recognizee the ongoing and
+significant contributions from developers outside Motorola, especially
+Jon Grimm and Daisy Chang of IBM, and Xingang Guo of Intel.
+
+\section{Availability}
+
+All the code discussed in this paper is available from the lksctp
+project on Source Forge:
+
+\begin{center}
+\texttt{http://sourceforge.net/projects/lksctp/}
+\end{center}
+
+\begin{thebibliography}{2001}
+
+\bibitem[RFC2960]{rfc2960} R.~Stewart, Q.~Xie, K.~Morneault, C.~Sharp,
+H.~J.~Schwarzbauer, T.~Taylor, I.~Rytina, M.~Kalla, L.~Zhang, and,
+V.~Paxson, {\em Stream Control Transmission Protocol}, RFC~2960 (Oct~2000).
+
+\bibitem[SCTPAPI]{api} R.~Stewart, Q.~Xie, L.~H.~P.~Yarroll, J.~Wood,
+K.~Poon, K.~Fujita., {\em Sockets API Extensions for SCTP}, Work In
+Progress, \texttt{draft-ietf-tsvwg-sctpsocket-00.txt} (Jun~2001).
+
+\bibitem[SCTPIMPL]{impl} R.~Stewart. {\it et al},
+{\em SCTP Implementor's Guide}, Work In Progress,
+\texttt{draft-ietf-tsvwg-sctpimpguide-00.txt} (Jun~2001).
+
+\bibitem[SCTPMIB]{mib} J.~Pastor, M.~Belinchon. {\em Stream Control
+Transmission Protocol Management Information Base using SMIv2}, Work
+In Progress, \texttt{draft-ietf-sigtran-sctp-mib-03.txt} (Feb~2001).
+
+\bibitem[XP]{xp} K.~Beck. {\em Extreme Programming Explained: Embrace
+Change}, Addison-Wesley Publishers (2000).
+
+\bibitem[SCTPORG]{sctporg}{\em Randall Stewart's SCTP site},\\
+\texttt{http://www.sctp.org}, (2001).
+
+\bibitem[SCTPDE]{sctpde}{\em T\"uxen/Jungmeier SCTP site},\\
+\texttt{http://www.sctp.de}, (2001).
+
+\end{thebibliography}
+
+\end{document}
diff --git a/doc/random_notes.txt b/doc/random_notes.txt
new file mode 100644
index 0000000..fba745d
--- /dev/null
+++ b/doc/random_notes.txt
@@ -0,0 +1,729 @@
+These are more random design notes I need to keep track of.
+
+Perhaps counterWork() should be replaced with direct counter
+manipulation. This violates the functional style of the state
+functions, but only a little bit...
+
+IRRELEVANT: The vtag return value should be subsumed into repl.
+IRRELEVANT: sctp_make_chunk() should NOT be called directly from these
+IRRELEVANT: functions.
+
+I am very unhappy with retval->link. That means a LOT of copying.
+
+DONE: Basic principle for host or network byte order:
+DONE: Network byte order should be as close to the network as
+DONE: possible.
+DONE: This means that the first routine to manipulate a particular header
+DONE: should convert from network byte order to host byte order as
+DONE: soon as it removes it gets it from the next lowest layer.
+DONE: Outbound, the last routine to touch a header before passing it
+DONE: to the next lower layer should convert it to network order. For
+DONE: queues, the routine at the top (closer to user space) does the
+DONE: conversion--inbound queues are converted to host order by the
+DONE: reader, outbound queues are converted to network order by the
+DONE: writer.
+DONE:
+DONE: Forget that smoke. The problem is that this entails reparsing the
+DONE: header when it comes time to pass it to the lower layer (e.g. you need
+DONE: to check the SCTP header for optional fields). The code which fills
+DONE: in a field should put it in network order.
+DONE:
+DONE: POSSIBLY on inbound, the code which parses the header should convert
+DONE: it to host order... But on outbound, packets should ALWAYS be in
+DONE: network byte order!
+
+
+OK, we need to add some stream handling. This means that we are
+updating sctp_create_asoc() among many other functions. I think we
+want some functions for dereferencing streams...
+
+
+DONE: NOTES FOR TSNMap
+DONE:
+DONE: Variables:
+DONE: uint8_t *TSNMap Array counting #chunks with each TSN
+DONE: uint8_t *TSNMapEnd TSNMap+TSN_MAP_SIZE
+DONE: uint8_t *TSNMapOverflow counters for TSNMapBase+TSN_MAP_SIZE;
+DONE: uint8_t *TSNMapCumulativePtr Cell for highest CumulativeTSNAck
+DONE: uint32_t TSNMapCumulative Actual TSN for *TSNMapCumulativePtr
+DONE: uint32_t TSNMapBase Actual TSN for *TSNMap
+DONE: long TSNMapGap chunk.TSN - TSNMapBase
+DONE:
+DONE: Constants:
+DONE: TSN_MAP_SIZE
+DONE:
+DONE: TSNMap and TSNMapOverflow point at two fixed buffers each of length
+DONE: TSN_MAP_SIZE. When TSNMapCumulativePtr passes TSNMapEnd (i.e. we send
+DONE: the SACK including that value), we swap TSNMap and TSNMapOverflow,
+DONE: clearing TSNMap.
+DONE:
+DONE: This work should be done OUTSIDE the state functions, as it requires
+DONE: modifying the map. It is sufficient for the state function to return
+DONE: TSNMapGap. Take care that TSNMapGap is never 0--we reserve this value
+DONE: to mean "no TSNMapGap".
+
+
+DONE: FIGURE THIS OUT--which structures represent PEER TSN's and which
+DONE: structures represent OUR TSN's.
+DONE:
+DONE: Rename the elements to peerTSN* and myTSN*.
+
+
+ERROR IN Section 6.1:
+
+ Note: The data sender SHOULD NOT use a TSN that is more than
+ 2**31 - 1 above the beginning TSN of the current send window.
+
+SHOULD be 2**16-1 because of the GAP ACKs.
+
+ERROR IN 12.2 Parameters necessary per association (i.e. the TCB):
+Ack State : This flag indicates if the next received packet
+ : is to be responded to with a SACK. This is initialized
+ : to 0. When a packet is received it is incremented.
+ : If this value reaches 2 or more, a SACK is sent and the
+ : value is reset to 0. Note: This is used only when no DATA
+ : chunks are received out of order. When DATA chunks are
+ : out of order, SACK's are not delayed (see Section 6).
+
+NOWHERE in Section 6 is this mentioned. We only generate immediate
+SACKs for DUPLICATED DATA chunks. Is this an omission in Section 6 or
+a left-over note in section 12.2?
+
+
+Section 6.1:
+
+ Before an endpoint transmits a DATA chunk, if any received DATA
+ chunks have not been acknowledged (e.g., due to delayed ack), the
+ sender should create a SACK and bundle it with the outbound DATA
+ chunk, as long as the size of the final SCTP packet does not exceed
+ the current MTU. See Section 6.2.
+
+I definately won't do this. What AWFUL layering!
+
+We have this REALLY WIERD bugoid. We SACK the first data chunk of the
+second packet containing data chunks. A careful reading of the spec
+suggests that this is legal. It kinda works, but we end up with more
+SACK timeouts than we might otherwise have... The fix is to split off
+the SACK generation code from the TSN-handling code and run it when we
+get either a NEW packet, or an empty input queue.
+
+
+
+OK: Section 6.2 does not explicitly discuss stopping T3-rtx. The worked
+OK: example suggests that T3-rtx should be canceled when the SACK is
+OK: lined up with the data chunk... Ah! Section 6.3...
+
+
+We really ought to do a sctp_create_* and sctp_free_* for all of the
+major objects including SCTP_transport.
+
+{DONE: Copy af_inet.c and hack it to support SCTP.
+
+If we were going to do SCTP as a kernel module, we'd do this:
+
+We can then socket.c:sock_unregister() the whole INET address family
+and then sock_register() our hacked af_inet...
+}
+
+
+SCTP_ULP_* is really two groups of things--request types and response
+types...
+
+DONE: We want to know whether the arguments to bind in sock.h:struct proto
+DONE: are user space addresses or kernel space addresses. To do that we
+DONE: want to find the tcp bind call. To do THAT we are looking for the
+DONE: place that struct proto *prot gets filled in for a TCP struct sock.
+
+
+API issue--how do you set options per association? Normal setsockopt
+will operate on an endpoint. This is mostly an issue for the
+UDP-style api. The current solution (v02) is that all associations on
+a single socket should all have the same options. I still don't like
+this.
+
+Write a free_endpoint(). Remember to free debug_name if allocated...
+
+DONE: Make sure that the API specifies a way for sendto() to use some kind
+DONE: of opaque identifier for the remote endpoint of an association. As
+DONE: observed before, it is a bad thing to use an IP address/port pair as
+DONE: the identifier for the remote endpoint...
+
+General BUG--sctp_bind() needs to check to see if somebody else is
+already using this transport address (unless REUSE_ADDR is set...)...
+
+sctp_do_sm() is responsible for actually discarding packets. We need
+a sctp_discard_packet_from_inqueue().
+
+Be sure to schedule the top half handling in sctp_input.c:sctp_v4_rcv().
+
+Keycode 64 is Meta_L, should be Backspace (or whatever that really
+is)...
+
+DONE: Should sctp_transmit_packet() clone the skb? [Yes. In fact we
+DONE: need a deep copy because of a bug in loopback. This problem
+DONE: sort of goes away with the creation of SCTP_packet.]
+
+- memcpy_toiovec() is for copying from a blob to an iovec...
+- after(), before(), and between() are for comparing 32bit wrapable
+ numbers...
+
+Where do theobromides live? Are they fat soluable?
+
+printf "D %x\nC %x\nI %x\nP %x\nT %x\n", retval->skb->data, retval->chunk_hdr, retval->subh.init_hdr, retval->param_hdr, retval->skb->tail
+
+
+set $chunk = retval->repl->chunk_hdr
+set $init = (struct sctpInitiation *)(sizeof(struct sctpChunkDesc) + (uint8_t *)$chunk)
+set $param1 = (struct sctpParamDesc *)(sizeof(struct sctpInitiation) + (uint8_t *)$init)
+set $param2 = (struct sctpParamDesc *)(ntohs($param1->paramLength) + (uint8_t *)$param1)
+set $sc = (struct sctpStateCookie *)$param2
+
+DONE: run_queue sctp_tq_sideffects needs while wrapper.
+
+OK: Important structures:
+OK: protocol.c: struct inet_protocol tcp_protocol (IP inbound linkage)
+OK: tcp_ipv4.c: struct proto tcp_prot (exceptions to inet_stream_ops)
+OK: af_inet.c: struct proto_ops inet_stream_ops (sockets interface)
+
+Another unimplemented feature: sctp_sendmsg() should select an
+ephemeral port if a port is not already set...
+
+Path MTU stuff: Send shutdown with rewound CumuTSNack. Is this a
+protocol violation?
+
+NO: Use larger TSN increment than 1? Allows subsequencing [This is
+NO: patently illegal. The correct solution involves MTU calculations...]
+
+Lowest of 3 largest MTU's for fragmentation? Probably.
+Allows 2 RWINs worth of backup?
+
+Immediate heartbeat on secondary when primary fails?
+(Use fastest response on heartbeat to select new primary, keeping MTU in mind)
+This is probably illegal. v13 added stricter rules about generating
+heartbeats.
+
+[p- use 3 largest RWINs to select...]
+
+[jm- pick top 3 thruputs (RWIN/Latency), pick lowest MTU for the new primary
+ address ]
+
+
+Here is what we did to set up the repository:
+
+$ cd /usr/src/linux_notes
+$ bzcat ~/linux-2.4.0-test11.tar.bz2 | tar xfp -
+$ CVSROOT=:pserver:knutson@postmort.em.cig.mot.com:/opt/cvs
+$ export CVSROOT
+$ cd linux
+$ cvs import -m "plain old 2.4.0 test11" linux knutson start
+[Note that this EXCLUDES net/core.]
+$ cd ..
+$ mv linux linux-2.4.0-test11
+$ cvs co linux
+$ cd linux-2.4.0-test11/net
+$ tar cfv - core | (cd ../../linux/net;tar xfp -)
+$ cd ../../linux
+$ cvs add net/core
+$ cvs add net/core/*.c
+$ cvs add net/core/Makefile
+$ cd net
+$ cvs commit -m "add core"
+$ cd ..
+[Now we create the branch.]
+$ cvs tag -b uml
+[Move to that branch.]
+$ cvs update -r uml
+$ touch foo
+$ bzcat ~/patch-2.4.0-test11.bz2 | patch -p1
+$ for a in $(find . -newer foo | grep -v CVS); do echo $a; cvs add $a; done 2>&1 | tee ../snart
+$ cvs commit -m "UML patch for 2.4.0-test11"
+$ cvs tag latest_uml
+
+2001 Jan 11
+When we close the socket, it shouldn't de-bind the endpoint. Any new
+socket attempting to bind that endpoint should get an error until that
+endpoint finally dies (from all of its associations dying).
+
+This issue comes up with the question of what should happen when we
+close the socket and attempt to immediately open a new socket and bind
+the same endpoint. Currently, we could bind the same endpoint in SCTP
+terms which would be a new endpoint in data structure terms and buy
+ourselves some confusion.
+
+DONE: Tue Jan 16 23:08:51 CST 2001
+DONE:
+DONE: We find that when we closed the socket (and nulled the ep->sk
+DONE: reference to it), we caused problems later on with chunks created for
+DONE: transmit. When we looked at TCP, we found that closing a TCP socket
+DONE: does not destroy it immediately--TCP also has post-close transactions.
+DONE:
+DONE: Solution: We use the ep->moribund flag to indicate when the socket is
+DONE: closed and do not immediately null the reference in ep.
+
+Wed Jan 17 01:21:40 CST 2001
+
+What happens when loop1 == loop2 in funtest1b (i.e., when the source &
+destination endpoints are identical)? We found out. You get a *real*
+simultaneous init and a burning desire to designate two loop addresses
+so you don't inadvertently put yourself in the same situation again.
+
+We will investigate more later, as this situation promises to test a
+potential weak point in the protocol (cf. siminit above).
+
+Tue Jan 30 14:50:39 CST 2001
+vendor: Linus
+release tag: linux-2_4_1
+
+DONE: We really ought to have a small utility functions file for test stuff
+DONE: (both live kernel and test frame).
+
+Here are all the timers:
+T1-init (per association)
+T1-cookie (per association)
+T3-rtx (per destination)
+heartbeat timer (per association)
+T2-shutdown (per association)
+?Per Destination Timer? (presumed to be T3-rtx)
+
+Mark each chunk with the transport it was transmitted on.
+
+When we transmit a chunk, we turn on the rtx timer for the destination
+if not on already. The chunk is then copied to q->transmitted. When
+we receive a sack, we turn off each timer corresponding to a TSN ACK'd
+by the SACK CTSN. This is because either everything got through, or
+the chunk outbound longest for a given destination got through.
+We then start the timers for destinations which still have chunks on
+q->transmitted, after moving the appropriate chunks to q->sacked.
+
+When a rtx timer expires for a destination, all the chunks on
+q->transmitted for that destination get moved to q->retransmit,
+which then get transmitted (a: at that time, b: when any chunks are
+transmitted, retransmissions go first, c: other).
+
+WHEN PUSHING A CHUNK FOR TRANMISSION
+
+
+
+WHEN TRANSMITTING A CHUNK
+Assign a TSN (if it doesn't already have one).
+Select a transport.
+If the T3-rtx for the transport is not running, start it.
+Make a copy to send. Move the original to q->transmitted.
+
+WHEN PROCESSING A SACK
+Walk q->transmitted, moving things to q->sacked if they were sacked.
+
+Walk chunk through q->sacked.
+ if chunk->TSN <= CTSN {
+ stop chunk->transport->T3RTX
+ free the chunk
+ }
+
+
+WHEN RTX TIMEOUT HAPPENS
+Walk chunk through q->transmitted
+ if chunk->transport is the one that timed out,
+ move chunk to q->retransmit.
+Trigger transmission.
+
+
+DONE: Cases for transport selection:
+DONE: 1) <silent>L</silent>User is idiot savant, picks path
+DONE: 2) Transmit on primary path
+DONE: 3) Retransmit on secondary path
+
+sctp_add_transport() does not check to see if the transport we are
+adding already exists. This COULD lead to having to fail the same
+transport address twice (or more...). A valid INIT packet will not
+list the same address twice (in which case the OTHER guy is screwing
+himself) and we haven't implemented add_ip.
+
+THE PLAN (for adding lost packet handling):
+DONE: Initialize the timer for each transport when the transport is created.
+Generate timer control events according to 6.3.2.
+Write the state function for 6.3.3.
+Write the timer side-effects function.
+
+ Here are random things we would put in an SCTP_packet:
+
+ SCTP header contents:
+ sh->source = htons(ep->port);
+ sh->destination = htons(asoc->c.peerInfo.port);
+ sh->verificationTag = htonl(asoc->c.peerInfo.init.initiateTag);
+ A list of of chunks
+ The total size of the chunks (incl padding)
+
+ Here are random things we would do to an SCTP_packet:
+
+ sctp_chunk_fits_in_packet(packet, chunk, transport)
+ sctp_append_chunk(packet, chunk)
+ sctp_transmit_packet(packet, transport)
+ INIT_PACKET(asoc, &packet)
+
+
+
+
+/* Try to send a chunk down to the network. */
+int
+sctp_commit_chunk_to_network(struct SCTP_packet *payload,
+ struct SCTP_chunk *chunk,
+ struct SCTP_transport *transport)
+{
+ int transmitted;
+ transmitted = sctp_append_chunk(payload, chunk, transport)) {
+ switch(transmitted) {
+ case SCTP_XMIT_PACKET_FULL:
+ case SCTP_XMIT_RWND_FULL:
+ sctp_transmit_packet(...);
+ INIT_PACKET(payload);
+ transmitted = sctp_append_chunk(payload, chunk, transport);
+ break;
+ default:
+ break; /* Default is to do nothing. */
+ }
+ return(transmitted);
+}
+
+sctp_append_chunk can fail with either SCTP_XMIT_RWND_FULL,
+SCTP_XMIT_MUST_FRAG (PMTU_FULL), or SCTP_XMIT_PACKET_FULL.
+
+
+/* This is how we handle the rtx_timeout single-packet-transmit. */
+ if (pushdown_chunk(payload, chunk, transport)
+ && rtx_timeout) {
+ return(error);
+ }
+
+
+Thu Apr 5 16:04:09 CDT 2001
+Our objective here is to replace the switch in inet_create() with a
+table with register/unregister methods.
+
+#define PROTOSW_PREV
+#define PROTOSW_NEXT
+
+struct inet_protosw inetsw[] = {
+ {list: {next: PROTOSW_NEXT,
+ prev: PROTOSW_PREV,
+ },
+ type: SOCK_STREAM,
+ protocol: IPPROTO_TCP,
+ prot4: &tcp_prot,
+ prot6: &tcpv6_prot,
+ ops4: &inet_stream_ops,
+ ops6: &inet6_stream_ops,
+
+ no_check: 0,
+ reuse: 0,
+ capability: -1,
+ },
+
+#if defined(CONFIG_IP_SCTP) || defined(CONFIG_IP_SCTP_MODULE)
+ {type: SOCK_SEQPACKET,
+ protocol: IPPROTO_SCTP,
+ prot4: &sctp_prot,
+ prot6: &sctpv6_prot,
+ ops4: &inet_seqpacket_ops,
+ ops6: &inet6_seqpacket_ops,
+
+ no_check: 0,
+ reuse: 0,
+ capability: -1,
+ },
+
+ {type: SOCK_STREAM,
+ protocol: IPPROTO_SCTP,
+ prot4: &sctp_conn_prot,
+ prot6: &sctpv6_conn_prot,
+ ops4: &inet_stream_ops,
+ ops6: &inet6_stream_ops,
+
+ no_check: 0,
+ reuse: 0,
+ capability: -1,
+ },
+#endif /* CONFIG_IP_SCTP || CONFIG_IP_SCTP_MODULE */
+
+ {type: SOCK_DGRAM,
+ protocol: IPPROTO_UDP,
+ prot4: &udp_prot,
+ prot6: &udpv6_prot,
+ ops4: &inet_dgram_ops,
+ ops6: &inet6_dgram_ops,
+
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 0,
+ capability: -1,
+ },
+
+
+ {type: SOCK_RAW,
+ protocol: IPPROTO_WILD, /* wildcard */
+ prot4: &raw_prot,
+ prot6: &rawv6_prot,
+ ops4: &inet_dgram_ops,
+ ops6: &inet6_dgram_ops,
+
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 1,
+ capability: CAP_NET_RAW,
+ },
+
+}; /* struct inet_protosw inetsw */
+
+Here are things that need to go in that table:
+
+The first two fields are the keys for the table.
+struct inet_protosw {
+ struct list_head list;
+ unsigned short type;
+ int protocol; /* This is the L4 protocol number. */
+ struct proto *prot;
+ struct proto_ops *ops;
+
+ char no_check;
+ unsigned char reuse;
+ int capability;
+};
+
+Set type to SOCK_WILD to represent a wildcard.
+Set protocol to IPPROTO_WILD to represent a wildcard.
+Set no_check to 0 if we want all checksums.
+Set reuse to 0 if we do not want to set sk->reuse.
+Set 'capability' to -1 if no special capability is needed.
+
+
+* protocol = IPPROTO_TCP; /* Layer 4 proto number */
+* prot = &tcp_prot; /* Switch table for this proto */
+* sock->ops = &inet_stream_ops; /* Switch tbl for this type */
+
+ sk->num = protocol;
+- sk->no_check = UDP_CSUM_DEFAULT;
+- sk->reuse = 1;
+
+
+
+ if (type == SOCK_RAW && protocol == IPPROTO_RAW)
+ sk->protinfo.af_inet.hdrincl = 1;
+
+
+if (SOCK_RAW == sock->type) {
+ if (!capable(CAP_NET_RAW))
+ goto free_and_badperm;
+ if (!protocol)
+ goto free_and_noproto;
+ prot = &raw_prot;
+ sk->reuse = 1;
+ sk->num = protocol;
+ sock->ops = &inet_dgram_ops;
+ if (protocol == IPPROTO_RAW)
+ sk->protinfo.af_inet.hdrincl = 1;
+} else {
+ lookup();
+}
+
+
+Supporting routines:
+int inet_protosw_register(struct inet_protosw *p);
+int inet_protosw_unregister(struct inet_protosw *p);
+
+
+Tue Apr 10 12:57:45 CDT 2001
+Question: Should SCTP_packet be a dependent subclass of
+SCTP_outqueue, or should SCTP_outqueue and SCTP_packet be independent
+smart pipes which we can glue together?
+
+Answer: We feel that the independent smart pipes make independent
+testing easier.
+
+
+Sat Apr 21 18:17:06 CDT 2001
+OK, here's what's going on. An INIT and an INIT ACK contain almost
+exactly the same parameters, except that an INIT ACK must contain a
+cookie (the one that the initiator needs to echo). In OUR
+implementation, we put the INIT packet in the cookie, so we really do
+most of the processing on the INIT when we get the COOKIE ECHO.
+
+Dilemma:
+
+ When do we convert the INIT to host byte forder? We want to
+ use the same code for all three cases: INIT, INIT ACK, COOKIE
+ ECHO. But if we convert for INIT, then the INIT packet in the
+ cookie (which is processed with the COOKIE ECHO) will be in
+ host byte order.
+
+Options:
+ 1. Leave the INIT in network byte order. All access must convert
+ to host byte order as needed. Blech. This violates our
+ existing conventions. Hmm. As long as we don't walk the
+ parameters again, we might be OK...
+
+ 2. Add an argument to sctp_process_param() telling whether or
+ not to convert the parameter.
+
+We chose option 1.
+
+We REALLY should unify sctp_make_init() and sctp_make_init_ack(). The
+only difference is the cookie in the INIT ACK.
+
+We might one day need a version of sctp_addto_chunk() called
+sctp_addto_param() which does NOT add extra padding.
+
+How can we get the initial TSN in sctp_unpack_cookie without first
+having processed the INIT packet buried in the cookie?
+
+Sat Apr 28 15:03:48 CDT 2001
+This MIGHT be a bug--look for places we use sizeof(struct iphdr)--
+possibly we might need to grub around in the sk_buff structure
+to find the TRUE length of the iphdr (including options).
+One of the places is where we initialize a struct SCTP_packet--we
+really need to know how big the ip header options are.
+
+I've walked all the way through to the point where we pass INIT_ACK
+down to IP--it looks OK. We DO parse the parameters correctly...
+
+Two bugs--bind loop1a not loop1 in the second bind, and
+sctp_bind_endpoint() should not let you bind the same address twice.
+There should be an approriate errno in the bind man page. EINVAL.
+
+
+Tue May 15 15:35:28 CDT 2001
+compaq3_paddedinitackOK.tcp
+ We ignore ABORT.
+datakinectics_2
+ We will send extra data before we get a COOKIE ACK...
+ We really lucked out and this implementation ran fine...
+sun (lost trace)
+ We have an INIT that causes an oops.
+telesoft2_lostsendings.tcp
+telesoft3_spicyinitack.tcp
+ This INIT ACK causes an oops.
+datakinectics_3
+ulticom_3
+ They transmitted GAP reports and we retransmitted a TSN which had
+ been gap ack'd.
+adax2_goodsend.tcp
+ We produce MANY SACK's in a row after delaying way too long.
+ The retransmissions did not get bundled.
+
+Mon May 21 17:06:56 CDT 2001
+sctp_make_abort() needs to build an SCTP packet, not just a chunk...
+How do we handle cause codes?
+
+I don't know, but here's some random lines pruned from
+sctp_init_packet...
+
+ packet->source_port = asoc->ep->port;
+ packet->destination_port = asoc->peer.port;
+ packet->verificationTag = asoc->peer.i.initiateTag;
+
+
+
+CHANGES NEEDED IN THE LINUX KERNEL to support SCTP:
+* - sockreg
+- both saddr and daddr need to be explicit arguments to the function
+ which takes packets for transmission--move these OUT of the
+ socket... Decouple d_addr from struct sock
+- bindx()
+- glue (elt in sk->tp_pinfo, etc...)
+
+We THINK we have the following items:
+- Per packet frag control (v6)
+- Unified PMTU discovery
+- iov-like sk_buff (to minimize copies)
+
+Fri Aug 17 10:58:35 CDT 2001
+Current thinking:
+
+INADDR_ANY semantics for TCP imply an abstraction of the IP
+interfaces--use any that exist, TCP could care less. This means if
+you add or delete interfaces at a lower level, this doesn't require
+more configuration for TCP.
+
+What this means for SCTP is that INADDR_ANY should also abstract the
+IP interfaces, so that when an association is initiated, we use all
+available IP interfaces, even if some have been added or deleted since
+boot.
+
+At bind, we grub for all interfaces and add them to the endpoint.
+After bind, if an interface is added...we know about it because
+ a) a connection came in on it and we're bound to INADDR_ANY--we add
+ the new transport to the list and use that for the association.
+ b) we initiate and...regrub for all existing interfaces?
+ c) hooks may exist to inform us when new IP interfaces rise
+ phoenix-like from the void (not pointer).
+
+Fri Aug 17 18:24:01 CDT 2001
+
+We need to look in ip6_input.c for IPPROTO_TCP and IPPROTO_UDP. This
+probably needs to use the registration table to do some
+comparisons...
+
+There are several functions in tcp_ipv6.c that we want for sctp. They
+are currently static; we want them to be exported.
+
+Tue Aug 21 13:09:09 CDT 2001
+
+This is a revised list of changes we need in the 2.4.x kernels to
+support SCTP. These are based in part on Bidulock's code:
+
+MUST HAVE:
++ inet_listen() hook for transport layer
++ Make tests for SOCK_STREAM more specific (add IPPROTO_TCP checks)
+? Look for references to IPPROTO_TCP and IPPROTO_UDP to see if they
+ are sufficiently uniform.
+
+REALLY OUGHT TO HAVE:
+- bindx() (Daisy)
+- sockreg (done, need to use)
+- netfilter
+
+Interface
+
++ inet_getname() hook for transport layer?
+ - small & simple hooks here.
+
++ The ability to append things to proc files (/proc/sys/net
+ specifically...)
+
+TCP-one-true-transport cruft
+- ip_setsockopt() hook (See SOCK_STREAM below.)
+- unified PMTU discovery (allegedly done, need to use)
+(See tcp_sync_mss)
+ SOLUTIONS:
+ - We could move the extension headers and PMTU stuff out to the socket.
+ - We could intercept this socket call in sctp_setsockopt, and do
+ the relevant fix up there. (LY characterizes as "flippin'
+ disgusting")
+ - We could use dst->pmtu (after all, TCP does...sort of...)
+
+Performance
+- decouple d_addr from struct sock (Andi Kleen)
+- zero-copy (done, need to use)
+- per packet IPv6 fragmentation control (allegedly done, need to use)
+ - Why did LY ask for this--he doesn't recall...
+
+---------------------------------------------------------------------------
+Tue Feb 10 11:26:26 PST 2004 La Monte
+
+One significant policy change which 1.0.0 should include is a bias toward
+performance issues.
+
+One principle I want to make sure survives performance improvements is
+readability. In particular, I still would like to put together a site
+hyperlinking LKSCTP with RFC2960 and supporting docs. It should be
+possible to ask "What code implements THIS section?" and "What mandated
+THIS piece of code?"
+
+Consequently, a performance enhancement should either improve readability
+or define a separate clearly marked fast-path. In particular, that class
+of speedups which collapses multiple decisions from different sections of
+the RFCs should probably use separate fast-path code.
+
+Separate fast-path code creates a maintenance problem, so fast-path code
+REALLY needs comments which point explicitly to the slow path. The slow-
+path code should where possible point to the corresponding fast path. It
+then becomes easier to check whether fixes for one path are relevant for
+the other as well.
+
+
diff --git a/doc/rfc2960.txt b/doc/rfc2960.txt
new file mode 100644
index 0000000..7054d55
--- /dev/null
+++ b/doc/rfc2960.txt
@@ -0,0 +1,7507 @@
+
+
+
+
+
+
+Network Working Group R. Stewart
+Request for Comments: 2960 Q. Xie
+Category: Standards Track Motorola
+ K. Morneault
+ C. Sharp
+ Cisco
+ H. Schwarzbauer
+ Siemens
+ T. Taylor
+ Nortel Networks
+ I. Rytina
+ Ericsson
+ M. Kalla
+ Telcordia
+ L. Zhang
+ UCLA
+ V. Paxson
+ ACIRI
+ October 2000
+
+
+ Stream Control Transmission Protocol
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This document describes the Stream Control Transmission Protocol
+ (SCTP). SCTP is designed to transport PSTN signaling messages over
+ IP networks, but is capable of broader applications.
+
+ SCTP is a reliable transport protocol operating on top of a
+ connectionless packet network such as IP. It offers the following
+ services to its users:
+
+ -- acknowledged error-free non-duplicated transfer of user data,
+ -- data fragmentation to conform to discovered path MTU size,
+
+
+
+
+Stewart, et al. Standards Track [Page 1]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ -- sequenced delivery of user messages within multiple streams,
+ with an option for order-of-arrival delivery of individual user
+ messages,
+ -- optional bundling of multiple user messages into a single SCTP
+ packet, and
+ -- network-level fault tolerance through supporting of multi-
+ homing at either or both ends of an association.
+
+ The design of SCTP includes appropriate congestion avoidance behavior
+ and resistance to flooding and masquerade attacks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 2]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+Table of Contents
+
+ 1. Introduction.................................................. 5
+ 1.1 Motivation.................................................. 6
+ 1.2 Architectural View of SCTP.................................. 6
+ 1.3 Functional View of SCTP..................................... 7
+ 1.3.1 Association Startup and Takedown........................ 8
+ 1.3.2 Sequenced Delivery within Streams....................... 9
+ 1.3.3 User Data Fragmentation................................. 9
+ 1.3.4 Acknowledgement and Congestion Avoidance................ 9
+ 1.3.5 Chunk Bundling ......................................... 10
+ 1.3.6 Packet Validation....................................... 10
+ 1.3.7 Path Management......................................... 11
+ 1.4 Key Terms................................................... 11
+ 1.5 Abbreviations............................................... 15
+ 1.6 Serial Number Arithmetic.................................... 15
+ 2. Conventions.................................................... 16
+ 3. SCTP packet Format............................................ 16
+ 3.1 SCTP Common Header Field Descriptions....................... 17
+ 3.2 Chunk Field Descriptions.................................... 18
+ 3.2.1 Optional/Variable-length Parameter Format............... 20
+ 3.3 SCTP Chunk Definitions...................................... 21
+ 3.3.1 Payload Data (DATA)..................................... 22
+ 3.3.2 Initiation (INIT)....................................... 24
+ 3.3.2.1 Optional or Variable Length Parameters.............. 26
+ 3.3.3 Initiation Acknowledgement (INIT ACK)................... 30
+ 3.3.3.1 Optional or Variable Length Parameters.............. 33
+ 3.3.4 Selective Acknowledgement (SACK)........................ 33
+ 3.3.5 Heartbeat Request (HEARTBEAT)........................... 37
+ 3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK)............... 38
+ 3.3.7 Abort Association (ABORT)............................... 39
+ 3.3.8 Shutdown Association (SHUTDOWN)......................... 40
+ 3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK)................. 40
+ 3.3.10 Operation Error (ERROR)................................ 41
+ 3.3.10.1 Invalid Stream Identifier.......................... 42
+ 3.3.10.2 Missing Mandatory Parameter........................ 43
+ 3.3.10.3 Stale Cookie Error................................. 43
+ 3.3.10.4 Out of Resource.................................... 44
+ 3.3.10.5 Unresolvable Address............................... 44
+ 3.3.10.6 Unrecognized Chunk Type............................ 44
+ 3.3.10.7 Invalid Mandatory Parameter........................ 45
+ 3.3.10.8 Unrecognized Parameters............................ 45
+ 3.3.10.9 No User Data....................................... 46
+ 3.3.10.10 Cookie Received While Shutting Down............... 46
+ 3.3.11 Cookie Echo (COOKIE ECHO).............................. 46
+ 3.3.12 Cookie Acknowledgement (COOKIE ACK).................... 47
+ 3.3.13 Shutdown Complete (SHUTDOWN COMPLETE).................. 48
+ 4. SCTP Association State Diagram................................. 48
+
+
+
+Stewart, et al. Standards Track [Page 3]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 5. Association Initialization..................................... 52
+ 5.1 Normal Establishment of an Association...................... 52
+ 5.1.1 Handle Stream Parameters................................ 54
+ 5.1.2 Handle Address Parameters............................... 54
+ 5.1.3 Generating State Cookie................................. 56
+ 5.1.4 State Cookie Processing................................. 57
+ 5.1.5 State Cookie Authentication............................. 57
+ 5.1.6 An Example of Normal Association Establishment.......... 58
+ 5.2 Handle Duplicate or unexpected INIT, INIT ACK, COOKIE ECHO,
+ and COOKIE ACK.............................................. 60
+ 5.2.1 Handle Duplicate INIT in COOKIE-WAIT
+ or COOKIE-ECHOED States................................. 60
+ 5.2.2 Unexpected INIT in States Other than CLOSED,
+ COOKIE-ECHOED, COOKIE-WAIT and SHUTDOWN-ACK-SENT........ 61
+ 5.2.3 Unexpected INIT ACK..................................... 61
+ 5.2.4 Handle a COOKIE ECHO when a TCB exists.................. 62
+ 5.2.4.1 An Example of a Association Restart................. 64
+ 5.2.5 Handle Duplicate COOKIE ACK............................. 66
+ 5.2.6 Handle Stale COOKIE Error............................... 66
+ 5.3 Other Initialization Issues................................. 67
+ 5.3.1 Selection of Tag Value.................................. 67
+ 6. User Data Transfer............................................. 67
+ 6.1 Transmission of DATA Chunks................................. 69
+ 6.2 Acknowledgement on Reception of DATA Chunks................. 70
+ 6.2.1 Tracking Peer's Receive Buffer Space.................... 73
+ 6.3 Management Retransmission Timer............................. 75
+ 6.3.1 RTO Calculation......................................... 75
+ 6.3.2 Retransmission Timer Rules.............................. 76
+ 6.3.3 Handle T3-rtx Expiration................................ 77
+ 6.4 Multi-homed SCTP Endpoints.................................. 78
+ 6.4.1 Failover from Inactive Destination Address.............. 79
+ 6.5 Stream Identifier and Stream Sequence Number................ 80
+ 6.6 Ordered and Unordered Delivery.............................. 80
+ 6.7 Report Gaps in Received DATA TSNs........................... 81
+ 6.8 Adler-32 Checksum Calculation............................... 82
+ 6.9 Fragmentation............................................... 83
+ 6.10 Bundling .................................................. 84
+ 7. Congestion Control .......................................... 85
+ 7.1 SCTP Differences from TCP Congestion Control................ 85
+ 7.2 SCTP Slow-Start and Congestion Avoidance.................... 87
+ 7.2.1 Slow-Start.............................................. 87
+ 7.2.2 Congestion Avoidance.................................... 89
+ 7.2.3 Congestion Control...................................... 89
+ 7.2.4 Fast Retransmit on Gap Reports.......................... 90
+ 7.3 Path MTU Discovery.......................................... 91
+ 8. Fault Management.............................................. 92
+ 8.1 Endpoint Failure Detection.................................. 92
+ 8.2 Path Failure Detection...................................... 92
+
+
+
+Stewart, et al. Standards Track [Page 4]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 8.3 Path Heartbeat.............................................. 93
+ 8.4 Handle "Out of the blue" Packets............................ 95
+ 8.5 Verification Tag............................................ 96
+ 8.5.1 Exceptions in Verification Tag Rules.................... 97
+ 9. Termination of Association..................................... 98
+ 9.1 Abort of an Association..................................... 98
+ 9.2 Shutdown of an Association.................................. 98
+ 10. Interface with Upper Layer....................................101
+ 10.1 ULP-to-SCTP................................................101
+ 10.2 SCTP-to-ULP................................................111
+ 11. Security Considerations.......................................114
+ 11.1 Security Objectives........................................114
+ 11.2 SCTP Responses To Potential Threats........................115
+ 11.2.1 Countering Insider Attacks.............................115
+ 11.2.2 Protecting against Data Corruption in the Network......115
+ 11.2.3 Protecting Confidentiality.............................115
+ 11.2.4 Protecting against Blind Denial of Service Attacks.....116
+ 11.2.4.1 Flooding...........................................116
+ 11.2.4.2 Blind Masquerade...................................118
+ 11.2.4.3 Improper Monopolization of Services................118
+ 11.3 Protection against Fraud and Repudiation...................119
+ 12. Recommended Transmission Control Block (TCB) Parameters.......120
+ 12.1 Parameters necessary for the SCTP instance.................120
+ 12.2 Parameters necessary per association (i.e. the TCB)........120
+ 12.3 Per Transport Address Data.................................122
+ 12.4 General Parameters Needed..................................123
+ 13. IANA Considerations...........................................123
+ 13.1 IETF-defined Chunk Extension...............................123
+ 13.2 IETF-defined Chunk Parameter Extension.....................124
+ 13.3 IETF-defined Additional Error Causes.......................124
+ 13.4 Payload Protocol Identifiers...............................125
+ 14. Suggested SCTP Protocol Parameter Values......................125
+ 15. Acknowledgements..............................................126
+ 16. Authors' Addresses............................................126
+ 17. References....................................................128
+ 18. Bibliography..................................................129
+ Appendix A .......................................................131
+ Appendix B .......................................................132
+ Full Copyright Statement .........................................134
+
+1. Introduction
+
+ This section explains the reasoning behind the development of the
+ Stream Control Transmission Protocol (SCTP), the services it offers,
+ and the basic concepts needed to understand the detailed description
+ of the protocol.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 5]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+1.1 Motivation
+
+ TCP [RFC793] has performed immense service as the primary means of
+ reliable data transfer in IP networks. However, an increasing number
+ of recent applications have found TCP too limiting, and have
+ incorporated their own reliable data transfer protocol on top of UDP
+ [RFC768]. The limitations which users have wished to bypass include
+ the following:
+
+ -- TCP provides both reliable data transfer and strict order-of-
+ transmission delivery of data. Some applications need reliable
+ transfer without sequence maintenance, while others would be
+ satisfied with partial ordering of the data. In both of these
+ cases the head-of-line blocking offered by TCP causes unnecessary
+ delay.
+
+ -- The stream-oriented nature of TCP is often an inconvenience.
+ Applications must add their own record marking to delineate their
+ messages, and must make explicit use of the push facility to
+ ensure that a complete message is transferred in a reasonable
+ time.
+
+ -- The limited scope of TCP sockets complicates the task of
+ providing highly-available data transfer capability using multi-
+ homed hosts.
+
+ -- TCP is relatively vulnerable to denial of service attacks, such
+ as SYN attacks.
+
+ Transport of PSTN signaling across the IP network is an application
+ for which all of these limitations of TCP are relevant. While this
+ application directly motivated the development of SCTP, other
+ applications may find SCTP a good match to their requirements.
+
+1.2 Architectural View of SCTP
+
+ SCTP is viewed as a layer between the SCTP user application ("SCTP
+ user" for short) and a connectionless packet network service such as
+ IP. The remainder of this document assumes SCTP runs on top of IP.
+ The basic service offered by SCTP is the reliable transfer of user
+ messages between peer SCTP users. It performs this service within
+ the context of an association between two SCTP endpoints. Section 10
+ of this document sketches the API which should exist at the boundary
+ between the SCTP and the SCTP user layers.
+
+ SCTP is connection-oriented in nature, but the SCTP association is a
+ broader concept than the TCP connection. SCTP provides the means for
+ each SCTP endpoint (Section 1.4) to provide the other endpoint
+
+
+
+Stewart, et al. Standards Track [Page 6]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ (during association startup) with a list of transport addresses
+ (i.e., multiple IP addresses in combination with an SCTP port)
+ through which that endpoint can be reached and from which it will
+ originate SCTP packets. The association spans transfers over all of
+ the possible source/destination combinations which may be generated
+ from each endpoint's lists.
+
+ _____________ _____________
+ | SCTP User | | SCTP User |
+ | Application | | Application |
+ |-------------| |-------------|
+ | SCTP | | SCTP |
+ | Transport | | Transport |
+ | Service | | Service |
+ |-------------| |-------------|
+ | |One or more ---- One or more| |
+ | IP Network |IP address \/ IP address| IP Network |
+ | Service |appearances /\ appearances| Service |
+ |_____________| ---- |_____________|
+
+ SCTP Node A |<-------- Network transport ------->| SCTP Node B
+
+ Figure 1: An SCTP Association
+
+1.3 Functional View of SCTP
+
+ The SCTP transport service can be decomposed into a number of
+ functions. These are depicted in Figure 2 and explained in the
+ remainder of this section.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 7]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ SCTP User Application
+
+ -----------------------------------------------------
+ _____________ ____________________
+ | | | Sequenced delivery |
+ | Association | | within streams |
+ | | |____________________|
+ | startup |
+ | | ____________________________
+ | and | | User Data Fragmentation |
+ | | |____________________________|
+ | takedown |
+ | | ____________________________
+ | | | Acknowledgement |
+ | | | and |
+ | | | Congestion Avoidance |
+ | | |____________________________|
+ | |
+ | | ____________________________
+ | | | Chunk Bundling |
+ | | |____________________________|
+ | |
+ | | ________________________________
+ | | | Packet Validation |
+ | | |________________________________|
+ | |
+ | | ________________________________
+ | | | Path Management |
+ |_____________| |________________________________|
+
+ Figure 2: Functional View of the SCTP Transport Service
+
+1.3.1 Association Startup and Takedown
+
+ An association is initiated by a request from the SCTP user (see the
+ description of the ASSOCIATE (or SEND) primitive in Section 10).
+
+ A cookie mechanism, similar to one described by Karn and Simpson in
+ [RFC2522], is employed during the initialization to provide
+ protection against security attacks. The cookie mechanism uses a
+ four-way handshake, the last two legs of which are allowed to carry
+ user data for fast setup. The startup sequence is described in
+ Section 5 of this document.
+
+ SCTP provides for graceful close (i.e., shutdown) of an active
+ association on request from the SCTP user. See the description of
+ the SHUTDOWN primitive in Section 10. SCTP also allows ungraceful
+ close (i.e., abort), either on request from the user (ABORT
+
+
+
+Stewart, et al. Standards Track [Page 8]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ primitive) or as a result of an error condition detected within the
+ SCTP layer. Section 9 describes both the graceful and the ungraceful
+ close procedures.
+
+ SCTP does not support a half-open state (like TCP) wherein one side
+ may continue sending data while the other end is closed. When either
+ endpoint performs a shutdown, the association on each peer will stop
+ accepting new data from its user and only deliver data in queue at
+ the time of the graceful close (see Section 9).
+
+1.3.2 Sequenced Delivery within Streams
+
+ The term "stream" is used in SCTP to refer to a sequence of user
+ messages that are to be delivered to the upper-layer protocol in
+ order with respect to other messages within the same stream. This is
+ in contrast to its usage in TCP, where it refers to a sequence of
+ bytes (in this document a byte is assumed to be eight bits).
+
+ The SCTP user can specify at association startup time the number of
+ streams to be supported by the association. This number is
+ negotiated with the remote end (see Section 5.1.1). User messages
+ are associated with stream numbers (SEND, RECEIVE primitives, Section
+ 10). Internally, SCTP assigns a stream sequence number to each
+ message passed to it by the SCTP user. On the receiving side, SCTP
+ ensures that messages are delivered to the SCTP user in sequence
+ within a given stream. However, while one stream may be blocked
+ waiting for the next in-sequence user message, delivery from other
+ streams may proceed.
+
+ SCTP provides a mechanism for bypassing the sequenced delivery
+ service. User messages sent using this mechanism are delivered to
+ the SCTP user as soon as they are received.
+
+1.3.3 User Data Fragmentation
+
+ When needed, SCTP fragments user messages to ensure that the SCTP
+ packet passed to the lower layer conforms to the path MTU. On
+ receipt, fragments are reassembled into complete messages before
+ being passed to the SCTP user.
+
+1.3.4 Acknowledgement and Congestion Avoidance
+
+ SCTP assigns a Transmission Sequence Number (TSN) to each user data
+ fragment or unfragmented message. The TSN is independent of any
+ stream sequence number assigned at the stream level. The receiving
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 9]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ end acknowledges all TSNs received, even if there are gaps in the
+ sequence. In this way, reliable delivery is kept functionally
+ separate from sequenced stream delivery.
+
+ The acknowledgement and congestion avoidance function is responsible
+ for packet retransmission when timely acknowledgement has not been
+ received. Packet retransmission is conditioned by congestion
+ avoidance procedures similar to those used for TCP. See Sections 6
+ and 7 for a detailed description of the protocol procedures
+ associated with this function.
+
+1.3.5 Chunk Bundling
+
+ As described in Section 3, the SCTP packet as delivered to the lower
+ layer consists of a common header followed by one or more chunks.
+ Each chunk may contain either user data or SCTP control information.
+ The SCTP user has the option to request bundling of more than one
+ user messages into a single SCTP packet. The chunk bundling function
+ of SCTP is responsible for assembly of the complete SCTP packet and
+ its disassembly at the receiving end.
+
+ During times of congestion an SCTP implementation MAY still perform
+ bundling even if the user has requested that SCTP not bundle. The
+ user's disabling of bundling only affects SCTP implementations that
+ may delay a small period of time before transmission (to attempt to
+ encourage bundling). When the user layer disables bundling, this
+ small delay is prohibited but not bundling that is performed during
+ congestion or retransmission.
+
+1.3.6 Packet Validation
+
+ A mandatory Verification Tag field and a 32 bit checksum field (see
+ Appendix B for a description of the Adler-32 checksum) are included
+ in the SCTP common header. The Verification Tag value is chosen by
+ each end of the association during association startup. Packets
+ received without the expected Verification Tag value are discarded,
+ as a protection against blind masquerade attacks and against stale
+ SCTP packets from a previous association. The Adler-32 checksum
+ should be set by the sender of each SCTP packet to provide additional
+ protection against data corruption in the network. The receiver of
+ an SCTP packet with an invalid Adler-32 checksum silently discards
+ the packet.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 10]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+1.3.7 Path Management
+
+ The sending SCTP user is able to manipulate the set of transport
+ addresses used as destinations for SCTP packets through the
+ primitives described in Section 10. The SCTP path management
+ function chooses the destination transport address for each outgoing
+ SCTP packet based on the SCTP user's instructions and the currently
+ perceived reachability status of the eligible destination set. The
+ path management function monitors reachability through heartbeats
+ when other packet traffic is inadequate to provide this information
+ and advises the SCTP user when reachability of any far-end transport
+ address changes. The path management function is also responsible
+ for reporting the eligible set of local transport addresses to the
+ far end during association startup, and for reporting the transport
+ addresses returned from the far end to the SCTP user.
+
+ At association start-up, a primary path is defined for each SCTP
+ endpoint, and is used for normal sending of SCTP packets.
+
+ On the receiving end, the path management is responsible for
+ verifying the existence of a valid SCTP association to which the
+ inbound SCTP packet belongs before passing it for further processing.
+
+ Note: Path Management and Packet Validation are done at the same
+ time, so although described separately above, in reality they cannot
+ be performed as separate items.
+
+1.4 Key Terms
+
+ Some of the language used to describe SCTP has been introduced in the
+ previous sections. This section provides a consolidated list of the
+ key terms and their definitions.
+
+ o Active destination transport address: A transport address on a
+ peer endpoint which a transmitting endpoint considers available
+ for receiving user messages.
+
+ o Bundling: An optional multiplexing operation, whereby more than
+ one user message may be carried in the same SCTP packet. Each
+ user message occupies its own DATA chunk.
+
+ o Chunk: A unit of information within an SCTP packet, consisting of
+ a chunk header and chunk-specific content.
+
+ o Congestion Window (cwnd): An SCTP variable that limits the data,
+ in number of bytes, a sender can send to a particular destination
+ transport address before receiving an acknowledgement.
+
+
+
+
+Stewart, et al. Standards Track [Page 11]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o Cumulative TSN Ack Point: The TSN of the last DATA chunk
+ acknowledged via the Cumulative TSN Ack field of a SACK.
+
+ o Idle destination address: An address that has not had user
+ messages sent to it within some length of time, normally the
+ HEARTBEAT interval or greater.
+
+ o Inactive destination transport address: An address which is
+ considered inactive due to errors and unavailable to transport
+ user messages.
+
+ o Message = user message: Data submitted to SCTP by the Upper Layer
+ Protocol (ULP).
+
+ o Message Authentication Code (MAC): An integrity check mechanism
+ based on cryptographic hash functions using a secret key.
+ Typically, message authentication codes are used between two
+ parties that share a secret key in order to validate information
+ transmitted between these parties. In SCTP it is used by an
+ endpoint to validate the State Cookie information that is returned
+ from the peer in the COOKIE ECHO chunk. The term "MAC" has
+ different meanings in different contexts. SCTP uses this term
+ with the same meaning as in [RFC2104].
+
+ o Network Byte Order: Most significant byte first, a.k.a., Big
+ Endian.
+
+ o Ordered Message: A user message that is delivered in order with
+ respect to all previous user messages sent within the stream the
+ message was sent on.
+
+ o Outstanding TSN (at an SCTP endpoint): A TSN (and the associated
+ DATA chunk) that has been sent by the endpoint but for which it
+ has not yet received an acknowledgement.
+
+ o Path: The route taken by the SCTP packets sent by one SCTP
+ endpoint to a specific destination transport address of its peer
+ SCTP endpoint. Sending to different destination transport
+ addresses does not necessarily guarantee getting separate paths.
+
+ o Primary Path: The primary path is the destination and source
+ address that will be put into a packet outbound to the peer
+ endpoint by default. The definition includes the source address
+ since an implementation MAY wish to specify both destination and
+ source address to better control the return path taken by reply
+ chunks and on which interface the packet is transmitted when the
+ data sender is multi-homed.
+
+
+
+
+Stewart, et al. Standards Track [Page 12]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o Receiver Window (rwnd): An SCTP variable a data sender uses to
+ store the most recently calculated receiver window of its peer, in
+ number of bytes. This gives the sender an indication of the space
+ available in the receiver's inbound buffer.
+
+ o SCTP association: A protocol relationship between SCTP endpoints,
+ composed of the two SCTP endpoints and protocol state information
+ including Verification Tags and the currently active set of
+ Transmission Sequence Numbers (TSNs), etc. An association can be
+ uniquely identified by the transport addresses used by the
+ endpoints in the association. Two SCTP endpoints MUST NOT have
+ more than one SCTP association between them at any given time.
+
+ o SCTP endpoint: The logical sender/receiver of SCTP packets. On a
+ multi-homed host, an SCTP endpoint is represented to its peers as
+ a combination of a set of eligible destination transport addresses
+ to which SCTP packets can be sent and a set of eligible source
+ transport addresses from which SCTP packets can be received. All
+ transport addresses used by an SCTP endpoint must use the same
+ port number, but can use multiple IP addresses. A transport
+ address used by an SCTP endpoint must not be used by another SCTP
+ endpoint. In other words, a transport address is unique to an
+ SCTP endpoint.
+
+ o SCTP packet (or packet): The unit of data delivery across the
+ interface between SCTP and the connectionless packet network
+ (e.g., IP). An SCTP packet includes the common SCTP header,
+ possible SCTP control chunks, and user data encapsulated within
+ SCTP DATA chunks.
+
+ o SCTP user application (SCTP user): The logical higher-layer
+ application entity which uses the services of SCTP, also called
+ the Upper-layer Protocol (ULP).
+
+ o Slow Start Threshold (ssthresh): An SCTP variable. This is the
+ threshold which the endpoint will use to determine whether to
+ perform slow start or congestion avoidance on a particular
+ destination transport address. Ssthresh is in number of bytes.
+
+ o Stream: A uni-directional logical channel established from one to
+ another associated SCTP endpoint, within which all user messages
+ are delivered in sequence except for those submitted to the
+ unordered delivery service.
+
+ Note: The relationship between stream numbers in opposite directions
+ is strictly a matter of how the applications use them. It is the
+ responsibility of the SCTP user to create and manage these
+ correlations if they are so desired.
+
+
+
+Stewart, et al. Standards Track [Page 13]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o Stream Sequence Number: A 16-bit sequence number used internally
+ by SCTP to assure sequenced delivery of the user messages within a
+ given stream. One stream sequence number is attached to each user
+ message.
+
+ o Tie-Tags: Verification Tags from a previous association. These
+ Tags are used within a State Cookie so that the newly restarting
+ association can be linked to the original association within the
+ endpoint that did not restart.
+
+ o Transmission Control Block (TCB): An internal data structure
+ created by an SCTP endpoint for each of its existing SCTP
+ associations to other SCTP endpoints. TCB contains all the status
+ and operational information for the endpoint to maintain and
+ manage the corresponding association.
+
+ o Transmission Sequence Number (TSN): A 32-bit sequence number used
+ internally by SCTP. One TSN is attached to each chunk containing
+ user data to permit the receiving SCTP endpoint to acknowledge its
+ receipt and detect duplicate deliveries.
+
+ o Transport address: A Transport Address is traditionally defined
+ by Network Layer address, Transport Layer protocol and Transport
+ Layer port number. In the case of SCTP running over IP, a
+ transport address is defined by the combination of an IP address
+ and an SCTP port number (where SCTP is the Transport protocol).
+
+ o Unacknowledged TSN (at an SCTP endpoint): A TSN (and the associated
+ DATA chunk) which has been received by the endpoint but for which
+ an acknowledgement has not yet been sent. Or in the opposite case,
+ for a packet that has been sent but no acknowledgement has been
+ received.
+
+ o Unordered Message: Unordered messages are "unordered" with respect
+ to any other message, this includes both other unordered messages
+ as well as other ordered messages. Unordered message might be
+ delivered prior to or later than ordered messages sent on the same
+ stream.
+
+ o User message: The unit of data delivery across the interface
+ between SCTP and its user.
+
+ o Verification Tag: A 32 bit unsigned integer that is randomly
+ generated. The Verification Tag provides a key that allows a
+ receiver to verify that the SCTP packet belongs to the current
+ association and is not an old or stale packet from a previous
+ association.
+
+
+
+
+Stewart, et al. Standards Track [Page 14]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+1.5. Abbreviations
+
+ MAC - Message Authentication Code [RFC2104]
+
+ RTO - Retransmission Time-out
+
+ RTT - Round-trip Time
+
+ RTTVAR - Round-trip Time Variation
+
+ SCTP - Stream Control Transmission Protocol
+
+ SRTT - Smoothed RTT
+
+ TCB - Transmission Control Block
+
+ TLV - Type-Length-Value Coding Format
+
+ TSN - Transmission Sequence Number
+
+ ULP - Upper-layer Protocol
+
+1.6 Serial Number Arithmetic
+
+ It is essential to remember that the actual Transmission Sequence
+ Number space is finite, though very large. This space ranges from 0
+ to 2**32 - 1. Since the space is finite, all arithmetic dealing with
+ Transmission Sequence Numbers must be performed modulo 2**32. This
+ unsigned arithmetic preserves the relationship of sequence numbers as
+ they cycle from 2**32 - 1 to 0 again. There are some subtleties to
+ computer modulo arithmetic, so great care should be taken in
+ programming the comparison of such values. When referring to TSNs,
+ the symbol "=<" means "less than or equal"(modulo 2**32).
+
+ Comparisons and arithmetic on TSNs in this document SHOULD use Serial
+ Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
+
+ An endpoint SHOULD NOT transmit a DATA chunk with a TSN that is more
+ than 2**31 - 1 above the beginning TSN of its current send window.
+ Doing so will cause problems in comparing TSNs.
+
+ Transmission Sequence Numbers wrap around when they reach 2**32 - 1.
+ That is, the next TSN a DATA chunk MUST use after transmitting TSN =
+ 2*32 - 1 is TSN = 0.
+
+ Any arithmetic done on Stream Sequence Numbers SHOULD use Serial
+ Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 16.
+
+
+
+
+Stewart, et al. Standards Track [Page 15]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ All other arithmetic and comparisons in this document uses normal
+ arithmetic.
+
+2. Conventions
+
+ The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+ SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+ they appear in this document, are to be interpreted as described in
+ [RFC2119].
+
+3. SCTP packet Format
+
+ An SCTP packet is composed of a common header and chunks. A chunk
+ contains either control information or user data.
+
+ The SCTP packet format is shown below:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Common Header |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk #1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk #n |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Multiple chunks can be bundled into one SCTP packet up to the MTU
+ size, except for the INIT, INIT ACK, and SHUTDOWN COMPLETE chunks.
+ These chunks MUST NOT be bundled with any other chunk in a packet.
+ See Section 6.10 for more details on chunk bundling.
+
+ If a user data message doesn't fit into one SCTP packet it can be
+ fragmented into multiple chunks using the procedure defined in
+ Section 6.9.
+
+ All integer fields in an SCTP packet MUST be transmitted in network
+ byte order, unless otherwise stated.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 16]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.1 SCTP Common Header Field Descriptions
+
+ SCTP Common Header Format
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Source Port Number | Destination Port Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Verification Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Checksum |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Source Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP sender's port number. It can be used by the
+ receiver in combination with the source IP address, the SCTP
+ destination port and possibly the destination IP address to
+ identify the association to which this packet belongs.
+
+ Destination Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP port number to which this packet is destined.
+ The receiving host will use this port number to de-multiplex the
+ SCTP packet to the correct receiving endpoint/application.
+
+ Verification Tag: 32 bits (unsigned integer)
+
+ The receiver of this packet uses the Verification Tag to validate
+ the sender of this SCTP packet. On transmit, the value of this
+ Verification Tag MUST be set to the value of the Initiate Tag
+ received from the peer endpoint during the association
+ initialization, with the following exceptions:
+
+ - A packet containing an INIT chunk MUST have a zero Verification
+ Tag.
+ - A packet containing a SHUTDOWN-COMPLETE chunk with the T-bit
+ set MUST have the Verification Tag copied from the packet with
+ the SHUTDOWN-ACK chunk.
+ - A packet containing an ABORT chunk may have the verification
+ tag copied from the packet which caused the ABORT to be sent.
+ For details see Section 8.4 and 8.5.
+
+ An INIT chunk MUST be the only chunk in the SCTP packet carrying it.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 17]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Checksum: 32 bits (unsigned integer)
+
+ This field contains the checksum of this SCTP packet. Its
+ calculation is discussed in Section 6.8. SCTP uses the Adler-
+ 32 algorithm as described in Appendix B for calculating the
+ checksum
+
+3.2 Chunk Field Descriptions
+
+ The figure below illustrates the field format for the chunks to be
+ transmitted in the SCTP packet. Each chunk is formatted with a Chunk
+ Type field, a chunk-specific Flag field, a Chunk Length field, and a
+ Value field.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Chunk Value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Type: 8 bits (unsigned integer)
+
+ This field identifies the type of information contained in the
+ Chunk Value field. It takes a value from 0 to 254. The value of
+ 255 is reserved for future use as an extension field.
+
+ The values of Chunk Types are defined as follows:
+
+ ID Value Chunk Type
+ ----- ----------
+ 0 - Payload Data (DATA)
+ 1 - Initiation (INIT)
+ 2 - Initiation Acknowledgement (INIT ACK)
+ 3 - Selective Acknowledgement (SACK)
+ 4 - Heartbeat Request (HEARTBEAT)
+ 5 - Heartbeat Acknowledgement (HEARTBEAT ACK)
+ 6 - Abort (ABORT)
+ 7 - Shutdown (SHUTDOWN)
+ 8 - Shutdown Acknowledgement (SHUTDOWN ACK)
+ 9 - Operation Error (ERROR)
+ 10 - State Cookie (COOKIE ECHO)
+ 11 - Cookie Acknowledgement (COOKIE ACK)
+ 12 - Reserved for Explicit Congestion Notification Echo (ECNE)
+ 13 - Reserved for Congestion Window Reduced (CWR)
+
+
+
+Stewart, et al. Standards Track [Page 18]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 14 - Shutdown Complete (SHUTDOWN COMPLETE)
+ 15 to 62 - reserved by IETF
+ 63 - IETF-defined Chunk Extensions
+ 64 to 126 - reserved by IETF
+ 127 - IETF-defined Chunk Extensions
+ 128 to 190 - reserved by IETF
+ 191 - IETF-defined Chunk Extensions
+ 192 to 254 - reserved by IETF
+ 255 - IETF-defined Chunk Extensions
+
+ Chunk Types are encoded such that the highest-order two bits specify
+ the action that must be taken if the processing endpoint does not
+ recognize the Chunk Type.
+
+ 00 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ 10 - Skip this chunk and continue processing.
+
+ 11 - Skip this chunk and continue processing, but report in an ERROR
+ Chunk using the 'Unrecognized Chunk Type' cause of error.
+
+ Note: The ECNE and CWR chunk types are reserved for future use of
+ Explicit Congestion Notification (ECN).
+
+ Chunk Flags: 8 bits
+
+ The usage of these bits depends on the chunk type as given by the
+ Chunk Type. Unless otherwise specified, they are set to zero on
+ transmit and are ignored on receipt.
+
+ Chunk Length: 16 bits (unsigned integer)
+
+ This value represents the size of the chunk in bytes including the
+ Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+ Therefore, if the Chunk Value field is zero-length, the Length
+ field will be set to 4. The Chunk Length field does not count any
+ padding.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 19]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Chunk Value: variable length
+
+ The Chunk Value field contains the actual information to be
+ transferred in the chunk. The usage and format of this field is
+ dependent on the Chunk Type.
+
+ The total length of a chunk (including Type, Length and Value fields)
+ MUST be a multiple of 4 bytes. If the length of the chunk is not a
+ multiple of 4 bytes, the sender MUST pad the chunk with all zero
+ bytes and this padding is not included in the chunk length field.
+ The sender should never pad with more than 3 bytes. The receiver
+ MUST ignore the padding bytes.
+
+ SCTP defined chunks are described in detail in Section 3.3. The
+ guidelines for IETF-defined chunk extensions can be found in Section
+ 13.1 of this document.
+
+3.2.1 Optional/Variable-length Parameter Format
+
+ Chunk values of SCTP control chunks consist of a chunk-type-specific
+ header of required fields, followed by zero or more parameters. The
+ optional and variable-length parameters contained in a chunk are
+ defined in a Type-Length-Value format as shown below.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Parameter Value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Parameter Type: 16 bits (unsigned integer)
+
+ The Type field is a 16 bit identifier of the type of parameter.
+ It takes a value of 0 to 65534.
+
+ The value of 65535 is reserved for IETF-defined extensions. Values
+ other than those defined in specific SCTP chunk description are
+ reserved for use by IETF.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 20]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Chunk Parameter Length: 16 bits (unsigned integer)
+
+ The Parameter Length field contains the size of the parameter in
+ bytes, including the Parameter Type, Parameter Length, and
+ Parameter Value fields. Thus, a parameter with a zero-length
+ Parameter Value field would have a Length field of 4. The
+ Parameter Length does not include any padding bytes.
+
+ Chunk Parameter Value: variable-length.
+
+ The Parameter Value field contains the actual information to be
+ transferred in the parameter.
+
+ The total length of a parameter (including Type, Parameter Length and
+ Value fields) MUST be a multiple of 4 bytes. If the length of the
+ parameter is not a multiple of 4 bytes, the sender pads the Parameter
+ at the end (i.e., after the Parameter Value field) with all zero
+ bytes. The length of the padding is not included in the parameter
+ length field. A sender SHOULD NOT pad with more than 3 bytes. The
+ receiver MUST ignore the padding bytes.
+
+ The Parameter Types are encoded such that the highest-order two bits
+ specify the action that must be taken if the processing endpoint does
+ not recognize the Parameter Type.
+
+ 00 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type' (in
+ either an ERROR or in the INIT ACK).
+
+ The actual SCTP parameters are defined in the specific SCTP chunk
+ sections. The rules for IETF-defined parameter extensions are
+ defined in Section 13.2.
+
+3.3 SCTP Chunk Definitions
+
+ This section defines the format of the different SCTP chunk types.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 21]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.1 Payload Data (DATA) (0)
+
+ The following format MUST be used for the DATA chunk:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0 | Reserved|U|B|E| Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream Identifier S | Stream Sequence Number n |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Payload Protocol Identifier |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / User Data (seq n of Stream S) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Reserved: 5 bits
+
+ Should be set to all '0's and ignored by the receiver.
+
+ U bit: 1 bit
+
+ The (U)nordered bit, if set to '1', indicates that this is an
+ unordered DATA chunk, and there is no Stream Sequence Number
+ assigned to this DATA chunk. Therefore, the receiver MUST ignore
+ the Stream Sequence Number field.
+
+ After re-assembly (if necessary), unordered DATA chunks MUST be
+ dispatched to the upper layer by the receiver without any attempt
+ to re-order.
+
+ If an unordered user message is fragmented, each fragment of the
+ message MUST have its U bit set to '1'.
+
+ B bit: 1 bit
+
+ The (B)eginning fragment bit, if set, indicates the first fragment
+ of a user message.
+
+ E bit: 1 bit
+
+ The (E)nding fragment bit, if set, indicates the last fragment of
+ a user message.
+
+
+
+
+Stewart, et al. Standards Track [Page 22]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ An unfragmented user message shall have both the B and E bits set to
+ '1'. Setting both B and E bits to '0' indicates a middle fragment of
+ a multi-fragment user message, as summarized in the following table:
+
+ B E Description
+ ============================================================
+ | 1 0 | First piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 0 0 | Middle piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 0 1 | Last piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 1 1 | Unfragmented Message |
+ ============================================================
+ | Table 1: Fragment Description Flags |
+ ============================================================
+
+ When a user message is fragmented into multiple chunks, the TSNs are
+ used by the receiver to reassemble the message. This means that the
+ TSNs for each fragment of a fragmented user message MUST be strictly
+ sequential.
+
+ Length: 16 bits (unsigned integer)
+
+ This field indicates the length of the DATA chunk in bytes from
+ the beginning of the type field to the end of the user data field
+ excluding any padding. A DATA chunk with no user data field will
+ have Length set to 16 (indicating 16 bytes).
+
+ TSN : 32 bits (unsigned integer)
+
+ This value represents the TSN for this DATA chunk. The valid
+ range of TSN is from 0 to 4294967295 (2**32 - 1). TSN wraps back
+ to 0 after reaching 4294967295.
+
+ Stream Identifier S: 16 bits (unsigned integer)
+
+ Identifies the stream to which the following user data belongs.
+
+ Stream Sequence Number n: 16 bits (unsigned integer)
+
+ This value represents the stream sequence number of the following
+ user data within the stream S. Valid range is 0 to 65535.
+
+ When a user message is fragmented by SCTP for transport, the same
+ stream sequence number MUST be carried in each of the fragments of
+ the message.
+
+
+
+
+Stewart, et al. Standards Track [Page 23]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Payload Protocol Identifier: 32 bits (unsigned integer)
+
+ This value represents an application (or upper layer) specified
+ protocol identifier. This value is passed to SCTP by its upper
+ layer and sent to its peer. This identifier is not used by SCTP
+ but can be used by certain network entities as well as the peer
+ application to identify the type of information being carried in
+ this DATA chunk. This field must be sent even in fragmented DATA
+ chunks (to make sure it is available for agents in the middle of
+ the network).
+
+ The value 0 indicates no application identifier is specified by
+ the upper layer for this payload data.
+
+ User Data: variable length
+
+ This is the payload user data. The implementation MUST pad the
+ end of the data to a 4 byte boundary with all-zero bytes. Any
+ padding MUST NOT be included in the length field. A sender MUST
+ never add more than 3 bytes of padding.
+
+3.3.2 Initiation (INIT) (1)
+
+ This chunk is used to initiate a SCTP association between two
+ endpoints. The format of the INIT chunk is shown below:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 1 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initiate Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit (a_rwnd) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Outbound Streams | Number of Inbound Streams |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initial TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Optional/Variable-Length Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The INIT chunk contains the following parameters. Unless otherwise
+ noted, each parameter MUST only be included once in the INIT chunk.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 24]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Fixed Parameters Status
+ ----------------------------------------------
+ Initiate Tag Mandatory
+ Advertised Receiver Window Credit Mandatory
+ Number of Outbound Streams Mandatory
+ Number of Inbound Streams Mandatory
+ Initial TSN Mandatory
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ IPv4 Address (Note 1) Optional 5
+ IPv6 Address (Note 1) Optional 6
+ Cookie Preservative Optional 9
+ Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
+ Host Name Address (Note 3) Optional 11
+ Supported Address Types (Note 4) Optional 12
+
+ Note 1: The INIT chunks can contain multiple addresses that can be
+ IPv4 and/or IPv6 in any combination.
+
+ Note 2: The ECN capable field is reserved for future use of Explicit
+ Congestion Notification.
+
+ Note 3: An INIT chunk MUST NOT contain more than one Host Name
+ address parameter. Moreover, the sender of the INIT MUST NOT combine
+ any other address types with the Host Name address in the INIT. The
+ receiver of INIT MUST ignore any other address types if the Host Name
+ address parameter is present in the received INIT chunk.
+
+ Note 4: This parameter, when present, specifies all the address types
+ the sending endpoint can support. The absence of this parameter
+ indicates that the sending endpoint can support any address type.
+
+ The Chunk Flags field in INIT is reserved and all bits in it should
+ be set to 0 by the sender and ignored by the receiver. The sequence
+ of parameters within an INIT can be processed in any order.
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT (the responding end) records the value of
+ the Initiate Tag parameter. This value MUST be placed into the
+ Verification Tag field of every SCTP packet that the receiver of
+ the INIT transmits within this association.
+
+ The Initiate Tag is allowed to have any value except 0. See
+ Section 5.3.1 for more on the selection of the tag value.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 25]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ If the value of the Initiate Tag in a received INIT chunk is found
+ to be 0, the receiver MUST treat it as an error and close the
+ association by transmitting an ABORT.
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This value represents the dedicated buffer space, in number of
+ bytes, the sender of the INIT has reserved in association with
+ this window. During the life of the association this buffer space
+ SHOULD not be lessened (i.e. dedicated buffers taken away from
+ this association); however, an endpoint MAY change the value of
+ a_rwnd it sends in SACK chunks.
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT
+ chunk wishes to create in this association. The value of 0 MUST
+ NOT be used.
+
+ Note: A receiver of an INIT with the OS value set to 0 SHOULD
+ abort the association.
+
+ Number of Inbound Streams (MIS) : 16 bits (unsigned integer)
+
+ Defines the maximum number of streams the sender of this INIT
+ chunk allows the peer end to create in this association. The
+ value 0 MUST NOT be used.
+
+ Note: There is no negotiation of the actual number of streams but
+ instead the two endpoints will use the min(requested, offered).
+ See Section 5.1.1 for details.
+
+ Note: A receiver of an INIT with the MIS value of 0 SHOULD abort
+ the association.
+
+ Initial TSN (I-TSN) : 32 bits (unsigned integer)
+
+ Defines the initial TSN that the sender will use. The valid range
+ is from 0 to 4294967295. This field MAY be set to the value of
+ the Initiate Tag field.
+
+3.3.2.1 Optional/Variable Length Parameters in INIT
+
+ The following parameters follow the Type-Length-Value format as
+ defined in Section 3.2.1. Any Type-Length-Value fields MUST come
+ after the fixed-length fields defined in the previous section.
+
+
+
+
+Stewart, et al. Standards Track [Page 26]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ IPv4 Address Parameter (5)
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 5 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv4 Address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ IPv4 Address: 32 bits (unsigned integer)
+
+ Contains an IPv4 address of the sending endpoint. It is binary
+ encoded.
+
+ IPv6 Address Parameter (6)
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 6 | Length = 20 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ | IPv6 Address |
+ | |
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ IPv6 Address: 128 bit (unsigned integer)
+
+ Contains an IPv6 address of the sending endpoint. It is binary
+ encoded.
+
+ Note: A sender MUST NOT use an IPv4-mapped IPv6 address [RFC2373]
+ but should instead use an IPv4 Address Parameter for an IPv4
+ address.
+
+ Combined with the Source Port Number in the SCTP common header,
+ the value passed in an IPv4 or IPv6 Address parameter indicates a
+ transport address the sender of the INIT will support for the
+ association being initiated. That is, during the lifetime of this
+ association, this IP address can appear in the source address
+ field of an IP datagram sent from the sender of the INIT, and can
+ be used as a destination address of an IP datagram sent from the
+ receiver of the INIT.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 27]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ More than one IP Address parameter can be included in an INIT
+ chunk when the INIT sender is multi-homed. Moreover, a multi-
+ homed endpoint may have access to different types of network, thus
+ more than one address type can be present in one INIT chunk, i.e.,
+ IPv4 and IPv6 addresses are allowed in the same INIT chunk.
+
+ If the INIT contains at least one IP Address parameter, then the
+ source address of the IP datagram containing the INIT chunk and
+ any additional address(es) provided within the INIT can be used as
+ destinations by the endpoint receiving the INIT. If the INIT does
+ not contain any IP Address parameters, the endpoint receiving the
+ INIT MUST use the source address associated with the received IP
+ datagram as its sole destination address for the association.
+
+ Note that not using any IP address parameters in the INIT and
+ INIT-ACK is an alternative to make an association more likely to
+ work across a NAT box.
+
+ Cookie Preservative (9)
+
+ The sender of the INIT shall use this parameter to suggest to the
+ receiver of the INIT for a longer life-span of the State Cookie.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 9 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Suggested Cookie Life-span Increment (msec.) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Suggested Cookie Life-span Increment: 32 bits (unsigned integer)
+
+ This parameter indicates to the receiver how much increment in
+ milliseconds the sender wishes the receiver to add to its default
+ cookie life-span.
+
+ This optional parameter should be added to the INIT chunk by the
+ sender when it re-attempts establishing an association with a peer
+ to which its previous attempt of establishing the association failed
+ due to a stale cookie operation error. The receiver MAY choose to
+ ignore the suggested cookie life-span increase for its own security
+ reasons.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 28]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Host Name Address (11)
+
+ The sender of INIT uses this parameter to pass its Host Name (in
+ place of its IP addresses) to its peer. The peer is responsible
+ for resolving the name. Using this parameter might make it more
+ likely for the association to work across a NAT box.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 11 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Host Name /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Host Name: variable length
+
+ This field contains a host name in "host name syntax" per RFC1123
+ Section 2.1 [RFC1123]. The method for resolving the host name is
+ out of scope of SCTP.
+
+ Note: At least one null terminator is included in the Host Name
+ string and must be included in the length.
+
+ Supported Address Types (12)
+
+ The sender of INIT uses this parameter to list all the address
+ types it can support.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 12 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Type #1 | Address Type #2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ......
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Address Type: 16 bits (unsigned integer)
+
+ This is filled with the type value of the corresponding address
+ TLV (e.g., IPv4 = 5, IPv6 = 6, Hostname = 11).
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 29]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.3 Initiation Acknowledgement (INIT ACK) (2):
+
+ The INIT ACK chunk is used to acknowledge the initiation of an SCTP
+ association.
+
+ The parameter part of INIT ACK is formatted similarly to the INIT
+ chunk. It uses two extra variable parameters: The State Cookie and
+ the Unrecognized Parameter:
+
+ The format of the INIT ACK chunk is shown below:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 2 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initiate Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Outbound Streams | Number of Inbound Streams |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initial TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Optional/Variable-Length Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT ACK records the value of the Initiate Tag
+ parameter. This value MUST be placed into the Verification Tag
+ field of every SCTP packet that the INIT ACK receiver transmits
+ within this association.
+
+ The Initiate Tag MUST NOT take the value 0. See Section 5.3.1 for
+ more on the selection of the Initiate Tag value.
+
+ If the value of the Initiate Tag in a received INIT ACK chunk is
+ found to be 0, the receiver MUST treat it as an error and close
+ the association by transmitting an ABORT.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 30]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This value represents the dedicated buffer space, in number of
+ bytes, the sender of the INIT ACK has reserved in association with
+ this window. During the life of the association this buffer space
+ SHOULD not be lessened (i.e. dedicated buffers taken away from
+ this association).
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT ACK
+ chunk wishes to create in this association. The value of 0 MUST
+ NOT be used.
+
+ Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+ destroy the association discarding its TCB.
+
+ Number of Inbound Streams (MIS) : 16 bits (unsigned integer)
+
+ Defines the maximum number of streams the sender of this INIT ACK
+ chunk allows the peer end to create in this association. The
+ value 0 MUST NOT be used.
+
+ Note: There is no negotiation of the actual number of streams but
+ instead the two endpoints will use the min(requested, offered).
+ See Section 5.1.1 for details.
+
+ Note: A receiver of an INIT ACK with the MIS value set to 0
+ SHOULD destroy the association discarding its TCB.
+
+ Initial TSN (I-TSN) : 32 bits (unsigned integer)
+
+ Defines the initial TSN that the INIT-ACK sender will use. The
+ valid range is from 0 to 4294967295. This field MAY be set to the
+ value of the Initiate Tag field.
+
+ Fixed Parameters Status
+ ----------------------------------------------
+ Initiate Tag Mandatory
+ Advertised Receiver Window Credit Mandatory
+ Number of Outbound Streams Mandatory
+ Number of Inbound Streams Mandatory
+ Initial TSN Mandatory
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 31]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ State Cookie Mandatory 7
+ IPv4 Address (Note 1) Optional 5
+ IPv6 Address (Note 1) Optional 6
+ Unrecognized Parameters Optional 8
+ Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
+ Host Name Address (Note 3) Optional 11
+
+ Note 1: The INIT ACK chunks can contain any number of IP address
+ parameters that can be IPv4 and/or IPv6 in any combination.
+
+ Note 2: The ECN capable field is reserved for future use of Explicit
+ Congestion Notification.
+
+ Note 3: The INIT ACK chunks MUST NOT contain more than one Host Name
+ address parameter. Moreover, the sender of the INIT ACK MUST NOT
+ combine any other address types with the Host Name address in the
+ INIT ACK. The receiver of the INIT ACK MUST ignore any other address
+ types if the Host Name address parameter is present.
+
+ IMPLEMENTATION NOTE: An implementation MUST be prepared to receive a
+ INIT ACK that is quite large (more than 1500 bytes) due to the
+ variable size of the state cookie AND the variable address list. For
+ example if a responder to the INIT has 1000 IPv4 addresses it wishes
+ to send, it would need at least 8,000 bytes to encode this in the
+ INIT ACK.
+
+ In combination with the Source Port carried in the SCTP common
+ header, each IP Address parameter in the INIT ACK indicates to the
+ receiver of the INIT ACK a valid transport address supported by the
+ sender of the INIT ACK for the lifetime of the association being
+ initiated.
+
+ If the INIT ACK contains at least one IP Address parameter, then the
+ source address of the IP datagram containing the INIT ACK and any
+ additional address(es) provided within the INIT ACK may be used as
+ destinations by the receiver of the INIT-ACK. If the INIT ACK does
+ not contain any IP Address parameters, the receiver of the INIT-ACK
+ MUST use the source address associated with the received IP datagram
+ as its sole destination address for the association.
+
+ The State Cookie and Unrecognized Parameters use the Type-Length-
+ Value format as defined in Section 3.2.1 and are described below.
+ The other fields are defined the same as their counterparts in the
+ INIT chunk.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 32]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.3.1 Optional or Variable Length Parameters
+
+ State Cookie
+
+ Parameter Type Value: 7
+
+ Parameter Length: variable size, depending on Size of Cookie
+
+ Parameter Value:
+
+ This parameter value MUST contain all the necessary state and
+ parameter information required for the sender of this INIT ACK
+ to create the association, along with a Message Authentication
+ Code (MAC). See Section 5.1.3 for details on State Cookie
+ definition.
+
+ Unrecognized Parameters:
+
+ Parameter Type Value: 8
+
+ Parameter Length: Variable Size.
+
+ Parameter Value:
+
+ This parameter is returned to the originator of the INIT chunk
+ when the INIT contains an unrecognized parameter which has a
+ value that indicates that it should be reported to the sender.
+ This parameter value field will contain unrecognized parameters
+ copied from the INIT chunk complete with Parameter Type, Length
+ and Value fields.
+
+3.3.4 Selective Acknowledgement (SACK) (3):
+
+ This chunk is sent to the peer endpoint to acknowledge received DATA
+ chunks and to inform the peer endpoint of gaps in the received
+ subsequences of DATA chunks as represented by their TSNs.
+
+ The SACK MUST contain the Cumulative TSN Ack and Advertised Receiver
+ Window Credit (a_rwnd) parameters.
+
+ By definition, the value of the Cumulative TSN Ack parameter is the
+ last TSN received before a break in the sequence of received TSNs
+ occurs; the next TSN value following this one has not yet been
+ received at the endpoint sending the SACK. This parameter therefore
+ acknowledges receipt of all TSNs less than or equal to its value.
+
+ The handling of a_rwnd by the receiver of the SACK is discussed in
+ detail in Section 6.2.1.
+
+
+
+Stewart, et al. Standards Track [Page 33]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The SACK also contains zero or more Gap Ack Blocks. Each Gap Ack
+ Block acknowledges a subsequence of TSNs received following a break
+ in the sequence of received TSNs. By definition, all TSNs
+ acknowledged by Gap Ack Blocks are greater than the value of the
+ Cumulative TSN Ack.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 3 |Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cumulative TSN Ack |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit (a_rwnd) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = X |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Gap Ack Block #1 Start | Gap Ack Block #1 End |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Gap Ack Block #N Start | Gap Ack Block #N End |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Duplicate TSN 1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Duplicate TSN X |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to all zeros on transmit and ignored on receipt.
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last DATA chunk received in
+ sequence before a gap.
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This field indicates the updated receive buffer space in bytes of
+ the sender of this SACK, see Section 6.2.1 for details.
+
+
+
+Stewart, et al. Standards Track [Page 34]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Number of Gap Ack Blocks: 16 bits (unsigned integer)
+
+ Indicates the number of Gap Ack Blocks included in this SACK.
+
+ Number of Duplicate TSNs: 16 bit
+
+ This field contains the number of duplicate TSNs the endpoint has
+ received. Each duplicate TSN is listed following the Gap Ack
+ Block list.
+
+ Gap Ack Blocks:
+
+ These fields contain the Gap Ack Blocks. They are repeated for
+ each Gap Ack Block up to the number of Gap Ack Blocks defined in
+ the Number of Gap Ack Blocks field. All DATA chunks with TSNs
+ greater than or equal to (Cumulative TSN Ack + Gap Ack Block
+ Start) and less than or equal to (Cumulative TSN Ack + Gap Ack
+ Block End) of each Gap Ack Block are assumed to have been received
+ correctly.
+
+ Gap Ack Block Start: 16 bits (unsigned integer)
+
+ Indicates the Start offset TSN for this Gap Ack Block. To
+ calculate the actual TSN number the Cumulative TSN Ack is added to
+ this offset number. This calculated TSN identifies the first TSN
+ in this Gap Ack Block that has been received.
+
+ Gap Ack Block End: 16 bits (unsigned integer)
+
+ Indicates the End offset TSN for this Gap Ack Block. To calculate
+ the actual TSN number the Cumulative TSN Ack is added to this
+ offset number. This calculated TSN identifies the TSN of the last
+ DATA chunk received in this Gap Ack Block.
+
+ For example, assume the receiver has the following DATA chunks newly
+ arrived at the time when it decides to send a Selective ACK,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 35]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ ----------
+ | TSN=17 |
+ ----------
+ | | <- still missing
+ ----------
+ | TSN=15 |
+ ----------
+ | TSN=14 |
+ ----------
+ | | <- still missing
+ ----------
+ | TSN=12 |
+ ----------
+ | TSN=11 |
+ ----------
+ | TSN=10 |
+ ----------
+
+ then, the parameter part of the SACK MUST be constructed as follows
+ (assuming the new a_rwnd is set to 4660 by the sender):
+
+ +--------------------------------+
+ | Cumulative TSN Ack = 12 |
+ +--------------------------------+
+ | a_rwnd = 4660 |
+ +----------------+---------------+
+ | num of block=2 | num of dup=0 |
+ +----------------+---------------+
+ |block #1 strt=2 |block #1 end=3 |
+ +----------------+---------------+
+ |block #2 strt=5 |block #2 end=5 |
+ +----------------+---------------+
+
+
+ Duplicate TSN: 32 bits (unsigned integer)
+
+ Indicates the number of times a TSN was received in duplicate
+ since the last SACK was sent. Every time a receiver gets a
+ duplicate TSN (before sending the SACK) it adds it to the list of
+ duplicates. The duplicate count is re-initialized to zero after
+ sending each SACK.
+
+ For example, if a receiver were to get the TSN 19 three times it
+ would list 19 twice in the outbound SACK. After sending the SACK
+ if it received yet one more TSN 19 it would list 19 as a duplicate
+ once in the next outgoing SACK.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 36]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.5 Heartbeat Request (HEARTBEAT) (4):
+
+ An endpoint should send this chunk to its peer endpoint to probe the
+ reachability of a particular destination transport address defined in
+ the present association.
+
+ The parameter field contains the Heartbeat Information which is a
+ variable length opaque data structure understood only by the sender.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 4 | Chunk Flags | Heartbeat Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Heartbeat Information TLV (Variable-Length) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+ Heartbeat Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and the Heartbeat Information field.
+
+ Heartbeat Information: variable length
+
+ Defined as a variable-length parameter using the format described
+ in Section 3.2.1, i.e.:
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ Heartbeat Info Mandatory 1
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Heartbeat Info Type=1 | HB Info Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Sender-specific Heartbeat Info /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 37]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The Sender-specific Heartbeat Info field should normally include
+ information about the sender's current time when this HEARTBEAT
+ chunk is sent and the destination transport address to which this
+ HEARTBEAT is sent (see Section 8.3).
+
+3.3.6 Heartbeat Acknowledgement (HEARTBEAT ACK) (5):
+
+ An endpoint should send this chunk to its peer endpoint as a response
+ to a HEARTBEAT chunk (see Section 8.3). A HEARTBEAT ACK is always
+ sent to the source IP address of the IP datagram containing the
+ HEARTBEAT chunk to which this ack is responding.
+
+ The parameter field contains a variable length opaque data structure.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 5 | Chunk Flags | Heartbeat Ack Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Heartbeat Information TLV (Variable-Length) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+ Heartbeat Ack Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and the Heartbeat Information field.
+
+ Heartbeat Information: variable length
+
+ This field MUST contain the Heartbeat Information parameter of
+ the Heartbeat Request to which this Heartbeat Acknowledgement is
+ responding.
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ Heartbeat Info Mandatory 1
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 38]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.7 Abort Association (ABORT) (6):
+
+ The ABORT chunk is sent to the peer of an association to close the
+ association. The ABORT chunk may contain Cause Parameters to inform
+ the receiver the reason of the abort. DATA chunks MUST NOT be
+ bundled with ABORT. Control chunks (except for INIT, INIT ACK and
+ SHUTDOWN COMPLETE) MAY be bundled with an ABORT but they MUST be
+ placed before the ABORT in the SCTP packet, or they will be ignored
+ by the receiver.
+
+ If an endpoint receives an ABORT with a format error or for an
+ association that doesn't exist, it MUST silently discard it.
+ Moreover, under any circumstances, an endpoint that receives an ABORT
+ MUST NOT respond to that ABORT by sending an ABORT of its own.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 6 |Reserved |T| Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / zero or more Error Causes /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Reserved: 7 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ T bit: 1 bit
+
+ The T bit is set to 0 if the sender had a TCB that it destroyed.
+ If the sender did not have a TCB it should set this bit to 1.
+
+ Note: Special rules apply to this chunk for verification, please see
+ Section 8.5.1 for details.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and all the Error Cause fields present.
+
+ See Section 3.3.10 for Error Cause definitions.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 39]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.8 Shutdown Association (SHUTDOWN) (7):
+
+ An endpoint in an association MUST use this chunk to initiate a
+ graceful close of the association with its peer. This chunk has the
+ following format.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 7 | Chunk Flags | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cumulative TSN Ack |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Indicates the length of the parameter. Set to 8.
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last chunk received in
+ sequence before any gaps.
+
+ Note: Since the SHUTDOWN message does not contain Gap Ack Blocks,
+ it cannot be used to acknowledge TSNs received out of order. In a
+ SACK, lack of Gap Ack Blocks that were previously included
+ indicates that the data receiver reneged on the associated DATA
+ chunks. Since SHUTDOWN does not contain Gap Ack Blocks, the
+ receiver of the SHUTDOWN shouldn't interpret the lack of a Gap Ack
+ Block as a renege. (see Section 6.2 for information on reneging)
+
+3.3.9 Shutdown Acknowledgement (SHUTDOWN ACK) (8):
+
+ This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+ chunk at the completion of the shutdown process, see Section 9.2 for
+ details.
+
+ The SHUTDOWN ACK chunk has no parameters.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 8 |Chunk Flags | Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+Stewart, et al. Standards Track [Page 40]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+3.3.10 Operation Error (ERROR) (9):
+
+ An endpoint sends this chunk to its peer endpoint to notify it of
+ certain error conditions. It contains one or more error causes. An
+ Operation Error is not considered fatal in and of itself, but may be
+ used with an ABORT chunk to report a fatal condition. It has the
+ following parameters:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 9 | Chunk Flags | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / one or more Error Causes /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and all the Error Cause fields present.
+
+ Error causes are defined as variable-length parameters using the
+ format described in 3.2.1, i.e.:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Cause-specific Information /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Cause Code: 16 bits (unsigned integer)
+
+ Defines the type of error conditions being reported.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 41]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+3.3.10.1 Invalid Stream Identifier (1)
+
+ Cause of error
+ ---------------
+ Invalid Stream Identifier: Indicates endpoint received a DATA chunk
+ sent to a nonexistent stream.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=1 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream Identifier | (Reserved) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Stream Identifier: 16 bits (unsigned integer)
+
+ Contains the Stream Identifier of the DATA chunk received in
+ error.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 42]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Reserved: 16 bits
+
+ This field is reserved. It is set to all 0's on transmit and
+ Ignored on receipt.
+
+3.3.10.2 Missing Mandatory Parameter (2)
+
+ Cause of error
+ ---------------
+ Missing Mandatory Parameter: Indicates that one or more mandatory
+ TLV parameters are missing in a received INIT or INIT ACK.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=2 | Cause Length=8+N*2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of missing params=N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Missing Param Type #1 | Missing Param Type #2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Missing Param Type #N-1 | Missing Param Type #N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Number of Missing params: 32 bits (unsigned integer)
+
+ This field contains the number of parameters contained in the
+ Cause-specific Information field.
+
+ Missing Param Type: 16 bits (unsigned integer)
+
+ Each field will contain the missing mandatory parameter number.
+
+3.3.10.3 Stale Cookie Error (3)
+
+ Cause of error
+ --------------
+ Stale Cookie Error: Indicates the receipt of a valid State Cookie
+ that has expired.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=3 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Measure of Staleness (usec.) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Measure of Staleness: 32 bits (unsigned integer)
+
+ This field contains the difference, in microseconds, between the
+ current time and the time the State Cookie expired.
+
+
+
+Stewart, et al. Standards Track [Page 43]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The sender of this error cause MAY choose to report how long past
+ expiration the State Cookie is by including a non-zero value in
+ the Measure of Staleness field. If the sender does not wish to
+ provide this information it should set the Measure of Staleness
+ field to the value of zero.
+
+3.3.10.4 Out of Resource (4)
+
+ Cause of error
+ ---------------
+ Out of Resource: Indicates that the sender is out of resource. This
+ is usually sent in combination with or within an ABORT.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=4 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.10.5 Unresolvable Address (5)
+
+ Cause of error
+ ---------------
+ Unresolvable Address: Indicates that the sender is not able to
+ resolve the specified address parameter (e.g., type of address is not
+ supported by the sender). This is usually sent in combination with
+ or within an ABORT.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=5 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unresolvable Address /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unresolvable Address: variable length
+
+ The unresolvable address field contains the complete Type, Length
+ and Value of the address parameter (or Host Name parameter) that
+ contains the unresolvable address or host name.
+
+3.3.10.6 Unrecognized Chunk Type (6)
+
+ Cause of error
+ ---------------
+ Unrecognized Chunk Type: This error cause is returned to the
+ originator of the chunk if the receiver does not understand the chunk
+ and the upper bits of the 'Chunk Type' are set to 01 or 11.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 44]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=6 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unrecognized Chunk /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unrecognized Chunk: variable length
+
+ The Unrecognized Chunk field contains the unrecognized Chunk from
+ the SCTP packet complete with Chunk Type, Chunk Flags and Chunk
+ Length.
+
+3.3.10.7 Invalid Mandatory Parameter (7)
+
+ Cause of error
+ ---------------
+ Invalid Mandatory Parameter: This error cause is returned to the
+ originator of an INIT or INIT ACK chunk when one of the mandatory
+ parameters is set to a invalid value.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=7 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.10.8 Unrecognized Parameters (8)
+
+ Cause of error
+ ---------------
+ Unrecognized Parameters: This error cause is returned to the
+ originator of the INIT ACK chunk if the receiver does not recognize
+ one or more Optional TLV parameters in the INIT ACK chunk.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=8 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unrecognized Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unrecognized Parameters: variable length
+
+ The Unrecognized Parameters field contains the unrecognized
+ parameters copied from the INIT ACK chunk complete with TLV. This
+ error cause is normally contained in an ERROR chunk bundled with
+ the COOKIE ECHO chunk when responding to the INIT ACK, when the
+ sender of the COOKIE ECHO chunk wishes to report unrecognized
+ parameters.
+
+
+
+Stewart, et al. Standards Track [Page 45]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.10.9 No User Data (9)
+
+ Cause of error
+ ---------------
+ No User Data: This error cause is returned to the originator of a
+ DATA chunk if a received DATA chunk has no user data.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=9 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / TSN value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ TSN value: 32 bits (+unsigned integer)
+
+ The TSN value field contains the TSN of the DATA chunk received
+ with no user data field.
+
+ This cause code is normally returned in an ABORT chunk (see
+ Section 6.2)
+
+3.3.10.10 Cookie Received While Shutting Down (10)
+
+ Cause of error
+ ---------------
+ Cookie Received While Shutting Down: A COOKIE ECHO was received
+ While the endpoint was in SHUTDOWN-ACK-SENT state. This error is
+ usually returned in an ERROR chunk bundled with the retransmitted
+ SHUTDOWN ACK.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=10 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.11 Cookie Echo (COOKIE ECHO) (10):
+
+ This chunk is used only during the initialization of an association.
+ It is sent by the initiator of an association to its peer to complete
+ the initialization process. This chunk MUST precede any DATA chunk
+ sent within the association, but MAY be bundled with one or more DATA
+ chunks in the same packet.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 46]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 10 |Chunk Flags | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Cookie /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bit
+
+ Set to zero on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the 4 bytes of
+ the chunk header and the size of the Cookie.
+
+ Cookie: variable size
+
+ This field must contain the exact cookie received in the State
+ Cookie parameter from the previous INIT ACK.
+
+ An implementation SHOULD make the cookie as small as possible to
+ insure interoperability.
+
+3.3.12 Cookie Acknowledgement (COOKIE ACK) (11):
+
+ This chunk is used only during the initialization of an association.
+ It is used to acknowledge the receipt of a COOKIE ECHO chunk. This
+ chunk MUST precede any DATA or SACK chunk sent within the
+ association, but MAY be bundled with one or more DATA chunks or SACK
+ chunk in the same SCTP packet.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 11 |Chunk Flags | Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to zero on transmit and ignored on receipt.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 47]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+3.3.13 Shutdown Complete (SHUTDOWN COMPLETE) (14):
+
+ This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+ ACK chunk at the completion of the shutdown process, see Section 9.2
+ for details.
+
+ The SHUTDOWN COMPLETE chunk has no parameters.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 14 |Reserved |T| Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Reserved: 7 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ T bit: 1 bit
+
+ The T bit is set to 0 if the sender had a TCB that it destroyed.
+ If the sender did not have a TCB it should set this bit to 1.
+
+ Note: Special rules apply to this chunk for verification, please see
+ Section 8.5.1 for details.
+
+4. SCTP Association State Diagram
+
+ During the lifetime of an SCTP association, the SCTP endpoint's
+ association progress from one state to another in response to various
+ events. The events that may potentially advance an association's
+ state include:
+
+ o SCTP user primitive calls, e.g., [ASSOCIATE], [SHUTDOWN], [ABORT],
+
+ o Reception of INIT, COOKIE ECHO, ABORT, SHUTDOWN, etc., control
+ chunks, or
+
+ o Some timeout events.
+
+ The state diagram in the figures below illustrates state changes,
+ together with the causing events and resulting actions. Note that
+ some of the error conditions are not shown in the state diagram.
+ Full description of all special cases should be found in the text.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 48]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Note: Chunk names are given in all capital letters, while parameter
+ names have the first letter capitalized, e.g., COOKIE ECHO chunk type
+ vs. State Cookie parameter. If more than one event/message can occur
+ which causes a state transition it is labeled (A), (B) etc.
+
+ ----- -------- (frm any state)
+ / \ / rcv ABORT [ABORT]
+ rcv INIT | | | ---------- or ----------
+ --------------- | v v delete TCB snd ABORT
+ generate Cookie \ +---------+ delete TCB
+ snd INIT ACK ---| CLOSED |
+ +---------+
+ / \ [ASSOCIATE]
+ / \ ---------------
+ | | create TCB
+ | | snd INIT
+ | | strt init timer
+ rcv valid | |
+ COOKIE ECHO | v
+ (1) ---------------- | +------------+
+ create TCB | | COOKIE-WAIT| (2)
+ snd COOKIE ACK | +------------+
+ | |
+ | | rcv INIT ACK
+ | | -----------------
+ | | snd COOKIE ECHO
+ | | stop init timer
+ | | strt cookie timer
+ | v
+ | +--------------+
+ | | COOKIE-ECHOED| (3)
+ | +--------------+
+ | |
+ | | rcv COOKIE ACK
+ | | -----------------
+ | | stop cookie timer
+ v v
+ +---------------+
+ | ESTABLISHED |
+ +---------------+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 49]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ (from the ESTABLISHED state only)
+ |
+ |
+ /--------+--------\
+ [SHUTDOWN] / \
+ -------------------| |
+ check outstanding | |
+ DATA chunks | |
+ v |
+ +---------+ |
+ |SHUTDOWN-| | rcv SHUTDOWN/check
+ |PENDING | | outstanding DATA
+ +---------+ | chunks
+ | |------------------
+ No more outstanding | |
+ ---------------------| |
+ snd SHUTDOWN | |
+ strt shutdown timer | |
+ v v
+ +---------+ +-----------+
+ (4) |SHUTDOWN-| | SHUTDOWN- | (5,6)
+ |SENT | | RECEIVED |
+ +---------+ +-----------+
+ | \ |
+ (A) rcv SHUTDOWN ACK | \ |
+ ----------------------| \ |
+ stop shutdown timer | \rcv:SHUTDOWN |
+ send SHUTDOWN COMPLETE| \ (B) |
+ delete TCB | \ |
+ | \ | No more outstanding
+ | \ |-----------------
+ | \ | send SHUTDOWN ACK
+ (B)rcv SHUTDOWN | \ | strt shutdown timer
+ ----------------------| \ |
+ send SHUTDOWN ACK | \ |
+ start shutdown timer | \ |
+ move to SHUTDOWN- | \ |
+ ACK-SENT | | |
+ | v |
+ | +-----------+
+ | | SHUTDOWN- | (7)
+ | | ACK-SENT |
+ | +----------+-
+ | | (C)rcv SHUTDOWN COMPLETE
+ | |-----------------
+ | | stop shutdown timer
+ | | delete TCB
+ | |
+
+
+
+Stewart, et al. Standards Track [Page 50]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ | | (D)rcv SHUTDOWN ACK
+ | |--------------
+ | | stop shutdown timer
+ | | send SHUTDOWN COMPLETE
+ | | delete TCB
+ | |
+ \ +---------+ /
+ \-->| CLOSED |<--/
+ +---------+
+
+ Figure 3: State Transition Diagram of SCTP
+
+ Notes:
+
+ 1) If the State Cookie in the received COOKIE ECHO is invalid (i.e.,
+ failed to pass the integrity check), the receiver MUST silently
+ discard the packet. Or, if the received State Cookie is expired
+ (see Section 5.1.5), the receiver MUST send back an ERROR chunk.
+ In either case, the receiver stays in the CLOSED state.
+
+ 2) If the T1-init timer expires, the endpoint MUST retransmit INIT
+ and re-start the T1-init timer without changing state. This MUST
+ be repeated up to 'Max.Init.Retransmits' times. After that, the
+ endpoint MUST abort the initialization process and report the
+ error to SCTP user.
+
+ 3) If the T1-cookie timer expires, the endpoint MUST retransmit
+ COOKIE ECHO and re-start the T1-cookie timer without changing
+ state. This MUST be repeated up to 'Max.Init.Retransmits' times.
+ After that, the endpoint MUST abort the initialization process and
+ report the error to SCTP user.
+
+ 4) In SHUTDOWN-SENT state the endpoint MUST acknowledge any received
+ DATA chunks without delay.
+
+ 5) In SHUTDOWN-RECEIVED state, the endpoint MUST NOT accept any new
+ send request from its SCTP user.
+
+ 6) In SHUTDOWN-RECEIVED state, the endpoint MUST transmit or
+ retransmit data and leave this state when all data in queue is
+ transmitted.
+
+ 7) In SHUTDOWN-ACK-SENT state, the endpoint MUST NOT accept any new
+ send request from its SCTP user.
+
+ The CLOSED state is used to indicate that an association is not
+ created (i.e., doesn't exist).
+
+
+
+
+Stewart, et al. Standards Track [Page 51]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+5. Association Initialization
+
+ Before the first data transmission can take place from one SCTP
+ endpoint ("A") to another SCTP endpoint ("Z"), the two endpoints must
+ complete an initialization process in order to set up an SCTP
+ association between them.
+
+ The SCTP user at an endpoint should use the ASSOCIATE primitive to
+ initialize an SCTP association to another SCTP endpoint.
+
+ IMPLEMENTATION NOTE: From an SCTP-user's point of view, an
+ association may be implicitly opened, without an ASSOCIATE primitive
+ (see 10.1 B) being invoked, by the initiating endpoint's sending of
+ the first user data to the destination endpoint. The initiating SCTP
+ will assume default values for all mandatory and optional parameters
+ for the INIT/INIT ACK.
+
+ Once the association is established, unidirectional streams are open
+ for data transfer on both ends (see Section 5.1.1).
+
+5.1 Normal Establishment of an Association
+
+ The initialization process consists of the following steps (assuming
+ that SCTP endpoint "A" tries to set up an association with SCTP
+ endpoint "Z" and "Z" accepts the new association):
+
+ A) "A" first sends an INIT chunk to "Z". In the INIT, "A" must
+ provide its Verification Tag (Tag_A) in the Initiate Tag field.
+ Tag_A SHOULD be a random number in the range of 1 to 4294967295
+ (see 5.3.1 for Tag value selection). After sending the INIT, "A"
+ starts the T1-init timer and enters the COOKIE-WAIT state.
+
+ B) "Z" shall respond immediately with an INIT ACK chunk. The
+ destination IP address of the INIT ACK MUST be set to the source
+ IP address of the INIT to which this INIT ACK is responding. In
+ the response, besides filling in other parameters, "Z" must set
+ the Verification Tag field to Tag_A, and also provide its own
+ Verification Tag (Tag_Z) in the Initiate Tag field.
+
+ Moreover, "Z" MUST generate and send along with the INIT ACK a
+ State Cookie. See Section 5.1.3 for State Cookie generation.
+
+ Note: After sending out INIT ACK with the State Cookie parameter,
+ "Z" MUST NOT allocate any resources, nor keep any states for the
+ new association. Otherwise, "Z" will be vulnerable to resource
+ attacks.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 52]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-
+ init timer and leave COOKIE-WAIT state. "A" shall then send the
+ State Cookie received in the INIT ACK chunk in a COOKIE ECHO
+ chunk, start the T1-cookie timer, and enter the COOKIE-ECHOED
+ state.
+
+ Note: The COOKIE ECHO chunk can be bundled with any pending
+ outbound DATA chunks, but it MUST be the first chunk in the packet
+ and until the COOKIE ACK is returned the sender MUST NOT send any
+ other packets to the peer.
+
+ D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply
+ with a COOKIE ACK chunk after building a TCB and moving to the
+ ESTABLISHED state. A COOKIE ACK chunk may be bundled with any
+ pending DATA chunks (and/or SACK chunks), but the COOKIE ACK chunk
+ MUST be the first chunk in the packet.
+
+ IMPLEMENTATION NOTE: An implementation may choose to send the
+ Communication Up notification to the SCTP user upon reception of a
+ valid COOKIE ECHO chunk.
+
+ E) Upon reception of the COOKIE ACK, endpoint "A" will move from the
+ COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-
+ cookie timer. It may also notify its ULP about the successful
+ establishment of the association with a Communication Up
+ notification (see Section 10).
+
+ An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.
+ They MUST be the only chunks present in the SCTP packets that carry
+ them.
+
+ An endpoint MUST send the INIT ACK to the IP address from which it
+ received the INIT.
+
+ Note: T1-init timer and T1-cookie timer shall follow the same rules
+ given in Section 6.3.
+
+ If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but
+ decides not to establish the new association due to missing mandatory
+ parameters in the received INIT or INIT ACK, invalid parameter
+ values, or lack of local resources, it MUST respond with an ABORT
+ chunk. It SHOULD also specify the cause of abort, such as the type
+ of the missing mandatory parameters, etc., by including the error
+ cause parameters with the ABORT chunk. The Verification Tag field in
+ the common header of the outbound SCTP packet containing the ABORT
+ chunk MUST be set to the Initiate Tag value of the peer.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 53]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ After the reception of the first DATA chunk in an association the
+ endpoint MUST immediately respond with a SACK to acknowledge the DATA
+ chunk. Subsequent acknowledgements should be done as described in
+ Section 6.2.
+
+ When the TCB is created, each endpoint MUST set its internal
+ Cumulative TSN Ack Point to the value of its transmitted Initial TSN
+ minus one.
+
+ IMPLEMENTATION NOTE: The IP addresses and SCTP port are generally
+ used as the key to find the TCB within an SCTP instance.
+
+5.1.1 Handle Stream Parameters
+
+ In the INIT and INIT ACK chunks, the sender of the chunk shall
+ indicate the number of outbound streams (OS) it wishes to have in the
+ association, as well as the maximum inbound streams (MIS) it will
+ accept from the other endpoint.
+
+ After receiving the stream configuration information from the other
+ side, each endpoint shall perform the following check: If the peer's
+ MIS is less than the endpoint's OS, meaning that the peer is
+ incapable of supporting all the outbound streams the endpoint wants
+ to configure, the endpoint MUST either use MIS outbound streams, or
+ abort the association and report to its upper layer the resources
+ shortage at its peer.
+
+ After the association is initialized, the valid outbound stream
+ identifier range for either endpoint shall be 0 to min(local OS,
+ remote MIS)-1.
+
+5.1.2 Handle Address Parameters
+
+ During the association initialization, an endpoint shall use the
+ following rules to discover and collect the destination transport
+ address(es) of its peer.
+
+ A) If there are no address parameters present in the received INIT or
+ INIT ACK chunk, the endpoint shall take the source IP address from
+ which the chunk arrives and record it, in combination with the
+ SCTP source port number, as the only destination transport address
+ for this peer.
+
+ B) If there is a Host Name parameter present in the received INIT or
+ INIT ACK chunk, the endpoint shall resolve that host name to a
+ list of IP address(es) and derive the transport address(es) of
+ this peer by combining the resolved IP address(es) with the SCTP
+ source port.
+
+
+
+Stewart, et al. Standards Track [Page 54]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The endpoint MUST ignore any other IP address parameters if they
+ are also present in the received INIT or INIT ACK chunk.
+
+ The time at which the receiver of an INIT resolves the host name
+ has potential security implications to SCTP. If the receiver of
+ an INIT resolves the host name upon the reception of the chunk,
+ and the mechanism the receiver uses to resolve the host name
+ involves potential long delay (e.g. DNS query), the receiver may
+ open itself up to resource attacks for the period of time while it
+ is waiting for the name resolution results before it can build the
+ State Cookie and release local resources.
+
+ Therefore, in cases where the name translation involves potential
+ long delay, the receiver of the INIT MUST postpone the name
+ resolution till the reception of the COOKIE ECHO chunk from the
+ peer. In such a case, the receiver of the INIT SHOULD build the
+ State Cookie using the received Host Name (instead of destination
+ transport addresses) and send the INIT ACK to the source IP
+ address from which the INIT was received.
+
+ The receiver of an INIT ACK shall always immediately attempt to
+ resolve the name upon the reception of the chunk.
+
+ The receiver of the INIT or INIT ACK MUST NOT send user data
+ (piggy-backed or stand-alone) to its peer until the host name is
+ successfully resolved.
+
+ If the name resolution is not successful, the endpoint MUST
+ immediately send an ABORT with "Unresolvable Address" error cause
+ to its peer. The ABORT shall be sent to the source IP address
+ from which the last peer packet was received.
+
+ C) If there are only IPv4/IPv6 addresses present in the received INIT
+ or INIT ACK chunk, the receiver shall derive and record all the
+ transport address(es) from the received chunk AND the source IP
+ address that sent the INIT or INIT ACK. The transport address(es)
+ are derived by the combination of SCTP source port (from the
+ common header) and the IP address parameter(s) carried in the INIT
+ or INIT ACK chunk and the source IP address of the IP datagram.
+ The receiver should use only these transport addresses as
+ destination transport addresses when sending subsequent packets to
+ its peer.
+
+ IMPLEMENTATION NOTE: In some cases (e.g., when the implementation
+ doesn't control the source IP address that is used for
+ transmitting), an endpoint might need to include in its INIT or
+ INIT ACK all possible IP addresses from which packets to the peer
+ could be transmitted.
+
+
+
+Stewart, et al. Standards Track [Page 55]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ After all transport addresses are derived from the INIT or INIT ACK
+ chunk using the above rules, the endpoint shall select one of the
+ transport addresses as the initial primary path.
+
+ Note: The INIT-ACK MUST be sent to the source address of the INIT.
+
+ The sender of INIT may include a 'Supported Address Types' parameter
+ in the INIT to indicate what types of address are acceptable. When
+ this parameter is present, the receiver of INIT (initiatee) MUST
+ either use one of the address types indicated in the Supported
+ Address Types parameter when responding to the INIT, or abort the
+ association with an "Unresolvable Address" error cause if it is
+ unwilling or incapable of using any of the address types indicated by
+ its peer.
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type, it
+ can abort the initiation process and then attempt a re-initiation by
+ using a 'Supported Address Types' parameter in the new INIT to
+ indicate what types of address it prefers.
+
+5.1.3 Generating State Cookie
+
+ When sending an INIT ACK as a response to an INIT chunk, the sender
+ of INIT ACK creates a State Cookie and sends it in the State Cookie
+ parameter of the INIT ACK. Inside this State Cookie, the sender
+ should include a MAC (see [RFC2104] for an example), a time stamp on
+ when the State Cookie is created, and the lifespan of the State
+ Cookie, along with all the information necessary for it to establish
+ the association.
+
+ The following steps SHOULD be taken to generate the State Cookie:
+
+ 1) Create an association TCB using information from both the received
+ INIT and the outgoing INIT ACK chunk,
+
+ 2) In the TCB, set the creation time to the current time of day, and
+ the lifespan to the protocol parameter 'Valid.Cookie.Life',
+
+ 3) From the TCB, identify and collect the minimal subset of
+ information needed to re-create the TCB, and generate a MAC using
+ this subset of information and a secret key (see [RFC2104] for an
+ example of generating a MAC), and
+
+ 4) Generate the State Cookie by combining this subset of information
+ and the resultant MAC.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 56]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ After sending the INIT ACK with the State Cookie parameter, the
+ sender SHOULD delete the TCB and any other local resource related to
+ the new association, so as to prevent resource attacks.
+
+ The hashing method used to generate the MAC is strictly a private
+ matter for the receiver of the INIT chunk. The use of a MAC is
+ mandatory to prevent denial of service attacks. The secret key
+ SHOULD be random ([RFC1750] provides some information on randomness
+ guidelines); it SHOULD be changed reasonably frequently, and the
+ timestamp in the State Cookie MAY be used to determine which key
+ should be used to verify the MAC.
+
+ An implementation SHOULD make the cookie as small as possible to
+ insure interoperability.
+
+5.1.4 State Cookie Processing
+
+ When an endpoint (in the COOKIE WAIT state) receives an INIT ACK
+ chunk with a State Cookie parameter, it MUST immediately send a
+ COOKIE ECHO chunk to its peer with the received State Cookie. The
+ sender MAY also add any pending DATA chunks to the packet after the
+ COOKIE ECHO chunk.
+
+ The endpoint shall also start the T1-cookie timer after sending out
+ the COOKIE ECHO chunk. If the timer expires, the endpoint shall
+ retransmit the COOKIE ECHO chunk and restart the T1-cookie timer.
+ This is repeated until either a COOKIE ACK is received or '
+ Max.Init.Retransmits' is reached causing the peer endpoint to be
+ marked unreachable (and thus the association enters the CLOSED
+ state).
+
+5.1.5 State Cookie Authentication
+
+ When an endpoint receives a COOKIE ECHO chunk from another endpoint
+ with which it has no association, it shall take the following
+ actions:
+
+ 1) Compute a MAC using the TCB data carried in the State Cookie and
+ the secret key (note the timestamp in the State Cookie MAY be used
+ to determine which secret key to use). Reference [RFC2104] can be
+ used as a guideline for generating the MAC,
+
+ 2) Authenticate the State Cookie as one that it previously generated
+ by comparing the computed MAC against the one carried in the State
+ Cookie. If this comparison fails, the SCTP packet, including the
+ COOKIE ECHO and any DATA chunks, should be silently discarded,
+
+
+
+
+
+Stewart, et al. Standards Track [Page 57]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 3) Compare the creation timestamp in the State Cookie to the current
+ local time. If the elapsed time is longer than the lifespan
+ carried in the State Cookie, then the packet, including the COOKIE
+ ECHO and any attached DATA chunks, SHOULD be discarded and the
+ endpoint MUST transmit an ERROR chunk with a "Stale Cookie" error
+ cause to the peer endpoint,
+
+ 4) If the State Cookie is valid, create an association to the sender
+ of the COOKIE ECHO chunk with the information in the TCB data
+ carried in the COOKIE ECHO, and enter the ESTABLISHED state,
+
+ 5) Send a COOKIE ACK chunk to the peer acknowledging reception of the
+ COOKIE ECHO. The COOKIE ACK MAY be bundled with an outbound DATA
+ chunk or SACK chunk; however, the COOKIE ACK MUST be the first
+ chunk in the SCTP packet.
+
+ 6) Immediately acknowledge any DATA chunk bundled with the COOKIE
+ ECHO with a SACK (subsequent DATA chunk acknowledgement should
+ follow the rules defined in Section 6.2). As mentioned in step
+ 5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+ MUST appear first in the SCTP packet.
+
+ If a COOKIE ECHO is received from an endpoint with which the receiver
+ of the COOKIE ECHO has an existing association, the procedures in
+ Section 5.2 should be followed.
+
+5.1.6 An Example of Normal Association Establishment
+
+ In the following example, "A" initiates the association and then
+ sends a user message to "Z", then "Z" sends two user messages to "A"
+ later (assuming no bundling or fragmentation occurs):
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 58]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Endpoint A Endpoint Z
+ {app sets association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A
+ & other info] --------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z)
+
+ /--- INIT ACK [Veri Tag=Tag_A,
+ / I-Tag=Tag_Z,
+ (Cancel T1-init timer) <------/ Cookie_Z, & other info]
+ (destroy temp TCB)
+ COOKIE ECHO [Cookie_Z] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED
+ state)
+
+
+ /---- COOKIE-ACK
+ /
+ (Cancel T1-init timer, <-----/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=1 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /----- SACK [TSN Ack=init
+ TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+
+ ...
+ {app sends 2 messages;strm 0}
+ /---- DATA
+ / [TSN=init TSN_Z
+ <--/ Strm=0,Seq=1 & user data 1]
+ SACK [TSN Ack=init TSN_Z, /---- DATA
+ Block=0] --------\ / [TSN=init TSN_Z +1,
+ \/ Strm=0,Seq=2 & user data 2]
+ <------/\
+ \
+ \------>
+
+ Figure 4: INITiation Example
+
+ If the T1-init timer expires at "A" after the INIT or COOKIE ECHO
+ chunks are sent, the same INIT or COOKIE ECHO chunk with the same
+ Initiate Tag (i.e., Tag_A) or State Cookie shall be retransmitted and
+
+
+
+Stewart, et al. Standards Track [Page 59]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ the timer restarted. This shall be repeated Max.Init.Retransmits
+ times before "A" considers "Z" unreachable and reports the failure to
+ its upper layer (and thus the association enters the CLOSED state).
+ When retransmitting the INIT, the endpoint MUST follow the rules
+ defined in 6.3 to determine the proper timer value.
+
+5.2 Handle Duplicate or Unexpected INIT, INIT ACK, COOKIE ECHO, and
+ COOKIE ACK
+
+ During the lifetime of an association (in one of the possible
+ states), an endpoint may receive from its peer endpoint one of the
+ setup chunks (INIT, INIT ACK, COOKIE ECHO, and COOKIE ACK). The
+ receiver shall treat such a setup chunk as a duplicate and process it
+ as described in this section.
+
+ Note: An endpoint will not receive the chunk unless the chunk was
+ sent to a SCTP transport address and is from a SCTP transport address
+ associated with this endpoint. Therefore, the endpoint processes
+ such a chunk as part of its current association.
+
+ The following scenarios can cause duplicated or unexpected chunks:
+
+ A) The peer has crashed without being detected, re-started itself and
+ sent out a new INIT chunk trying to restore the association,
+
+ B) Both sides are trying to initialize the association at about the
+ same time,
+
+ C) The chunk is from a stale packet that was used to establish the
+ present association or a past association that is no longer in
+ existence,
+
+ D) The chunk is a false packet generated by an attacker, or
+
+ E) The peer never received the COOKIE ACK and is retransmitting its
+ COOKIE ECHO.
+
+ The rules in the following sections shall be applied in order to
+ identify and correctly handle these cases.
+
+5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)
+
+ This usually indicates an initialization collision, i.e., each
+ endpoint is attempting, at about the same time, to establish an
+ association with the other endpoint.
+
+ Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
+ endpoint MUST respond with an INIT ACK using the same parameters it
+
+
+
+Stewart, et al. Standards Track [Page 60]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ sent in its original INIT chunk (including its Initiation Tag,
+ unchanged). These original parameters are combined with those from
+ the newly received INIT chunk. The endpoint shall also generate a
+ State Cookie with the INIT ACK. The endpoint uses the parameters
+ sent in its INIT to calculate the State Cookie.
+
+ After that, the endpoint MUST NOT change its state, the T1-init timer
+ shall be left running and the corresponding TCB MUST NOT be
+ destroyed. The normal procedures for handling State Cookies when a
+ TCB exists will resolve the duplicate INITs to a single association.
+
+ For an endpoint that is in the COOKIE-ECHOED state it MUST populate
+ its Tie-Tags with the Tag information of itself and its peer (see
+ section 5.2.2 for a description of the Tie-Tags).
+
+5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
+ COOKIE-WAIT and SHUTDOWN-ACK-SENT
+
+ Unless otherwise stated, upon reception of an unexpected INIT for
+ this association, the endpoint shall generate an INIT ACK with a
+ State Cookie. In the outbound INIT ACK the endpoint MUST copy its
+ current Verification Tag and peer's Verification Tag into a reserved
+ place within the state cookie. We shall refer to these locations as
+ the Peer's-Tie-Tag and the Local-Tie-Tag. The outbound SCTP packet
+ containing this INIT ACK MUST carry a Verification Tag value equal to
+ the Initiation Tag found in the unexpected INIT. And the INIT ACK
+ MUST contain a new Initiation Tag (randomly generated see Section
+ 5.3.1). Other parameters for the endpoint SHOULD be copied from the
+ existing parameters of the association (e.g. number of outbound
+ streams) into the INIT ACK and cookie.
+
+ After sending out the INIT ACK, the endpoint shall take no further
+ actions, i.e., the existing association, including its current state,
+ and the corresponding TCB MUST NOT be changed.
+
+ Note: Only when a TCB exists and the association is not in a COOKIE-
+ WAIT state are the Tie-Tags populated. For a normal association INIT
+ (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be
+ set to 0 (indicating that no previous TCB existed). The INIT ACK and
+ State Cookie are populated as specified in section 5.2.1.
+
+5.2.3 Unexpected INIT ACK
+
+ If an INIT ACK is received by an endpoint in any state other than the
+ COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
+ An unexpected INIT ACK usually indicates the processing of an old or
+ duplicated INIT chunk.
+
+
+
+
+Stewart, et al. Standards Track [Page 61]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+5.2.4 Handle a COOKIE ECHO when a TCB exists
+
+ When a COOKIE ECHO chunk is received by an endpoint in any state for
+ an existing association (i.e., not in the CLOSED state) the following
+ rules shall be applied:
+
+ 1) Compute a MAC as described in Step 1 of Section 5.1.5,
+
+ 2) Authenticate the State Cookie as described in Step 2 of Section
+ 5.1.5 (this is case C or D above).
+
+ 3) Compare the timestamp in the State Cookie to the current time. If
+ the State Cookie is older than the lifespan carried in the State
+ Cookie and the Verification Tags contained in the State Cookie do
+ not match the current association's Verification Tags, the packet,
+ including the COOKIE ECHO and any DATA chunks, should be
+ discarded. The endpoint also MUST transmit an ERROR chunk with a
+ "Stale Cookie" error cause to the peer endpoint (this is case C or
+ D in section 5.2).
+
+ If both Verification Tags in the State Cookie match the
+ Verification Tags of the current association, consider the State
+ Cookie valid (this is case E of section 5.2) even if the lifespan
+ is exceeded.
+
+ 4) If the State Cookie proves to be valid, unpack the TCB into a
+ temporary TCB.
+
+ 5) Refer to Table 2 to determine the correct action to be taken.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 62]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
++------------+------------+---------------+--------------+-------------+
+| Local Tag | Peer's Tag | Local-Tie-Tag |Peer's-Tie-Tag| Action/ |
+| | | | | Description |
++------------+------------+---------------+--------------+-------------+
+| X | X | M | M | (A) |
++------------+------------+---------------+--------------+-------------+
+| M | X | A | A | (B) |
++------------+------------+---------------+--------------+-------------+
+| M | 0 | A | A | (B) |
++------------+------------+---------------+--------------+-------------+
+| X | M | 0 | 0 | (C) |
++------------+------------+---------------+--------------+-------------+
+| M | M | A | A | (D) |
++======================================================================+
+| Table 2: Handling of a COOKIE ECHO when a TCB exists |
++======================================================================+
+
+ Legend:
+
+ X - Tag does not match the existing TCB
+ M - Tag matches the existing TCB.
+ 0 - No Tie-Tag in Cookie (unknown).
+ A - All cases, i.e. M, X or 0.
+
+ Note: For any case not shown in Table 2, the cookie should be
+ silently discarded.
+
+ Action
+
+ A) In this case, the peer may have restarted. When the endpoint
+ recognizes this potential 'restart', the existing session is
+ treated the same as if it received an ABORT followed by a new
+ COOKIE ECHO with the following exceptions:
+
+ - Any SCTP DATA Chunks MAY be retained (this is an implementation
+ specific option).
+
+ - A notification of RESTART SHOULD be sent to the ULP instead of
+ a "COMMUNICATION LOST" notification.
+
+ All the congestion control parameters (e.g., cwnd, ssthresh)
+ related to this peer MUST be reset to their initial values (see
+ Section 6.2.1).
+
+ After this the endpoint shall enter the ESTABLISHED state.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 63]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
+ the peer has restarted (Action A), it MUST NOT setup a new
+ association but instead resend the SHUTDOWN ACK and send an ERROR
+ chunk with a "Cookie Received while Shutting Down" error cause to
+ its peer.
+
+ B) In this case, both sides may be attempting to start an association
+ at about the same time but the peer endpoint started its INIT
+ after responding to the local endpoint's INIT. Thus it may have
+ picked a new Verification Tag not being aware of the previous Tag
+ it had sent this endpoint. The endpoint should stay in or enter
+ the ESTABLISHED state but it MUST update its peer's Verification
+ Tag from the State Cookie, stop any init or cookie timers that may
+ running and send a COOKIE ACK.
+
+ C) In this case, the local endpoint's cookie has arrived late.
+ Before it arrived, the local endpoint sent an INIT and received an
+ INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag
+ but a new tag of its own. The cookie should be silently
+ discarded. The endpoint SHOULD NOT change states and should leave
+ any timers running.
+
+ D) When both local and remote tags match the endpoint should always
+ enter the ESTABLISHED state, if it has not already done so. It
+ should stop any init or cookie timers that may be running and send
+ a COOKIE ACK.
+
+ Note: The "peer's Verification Tag" is the tag received in the
+ Initiate Tag field of the INIT or INIT ACK chunk.
+
+5.2.4.1 An Example of a Association Restart
+
+ In the following example, "A" initiates the association after a
+ restart has occurred. Endpoint "Z" had no knowledge of the restart
+ until the exchange (i.e. Heartbeats had not yet detected the failure
+ of "A"). (assuming no bundling or fragmentation occurs):
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 64]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+Endpoint A Endpoint Z
+<-------------- Association is established---------------------->
+Tag=Tag_A Tag=Tag_Z
+<--------------------------------------------------------------->
+{A crashes and restarts}
+{app sets up a association with Z}
+(build TCB)
+INIT [I-Tag=Tag_A'
+ & other info] --------\
+(Start T1-init timer) \
+(Enter COOKIE-WAIT state) \---> (find a existing TCB
+ compose temp TCB and Cookie_Z
+ with Tie-Tags to previous
+ association)
+ /--- INIT ACK [Veri Tag=Tag_A',
+ / I-Tag=Tag_Z',
+(Cancel T1-init timer) <------/ Cookie_Z[TieTags=
+ Tag_A,Tag_Z
+ & other info]
+ (destroy temp TCB,leave original
+ in place)
+COOKIE ECHO [Veri=Tag_Z',
+ Cookie_Z
+ Tie=Tag_A,
+ Tag_Z]----------\
+(Start T1-init timer) \
+(Enter COOKIE-ECHOED state) \---> (Find existing association,
+ Tie-Tags match old tags,
+ Tags do not match i.e.
+ case X X M M above,
+ Announce Restart to ULP
+ and reset association).
+ /---- COOKIE-ACK
+ /
+(Cancel T1-init timer, <-----/
+ Enter ESTABLISHED state)
+{app sends 1st user data; strm 0}
+DATA [TSN=initial TSN_A
+ Strm=0,Seq=1 & user data]--\
+(Start T3-rtx timer) \
+ \->
+ /----- SACK [TSN Ack=init TSN_A,Block=0]
+(Cancel T3-rtx timer) <------/
+
+ Figure 5: A Restart Example
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 65]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+5.2.5 Handle Duplicate COOKIE-ACK.
+
+ At any state other than COOKIE-ECHOED, an endpoint should silently
+ discard a received COOKIE ACK chunk.
+
+5.2.6 Handle Stale COOKIE Error
+
+ Receipt of an ERROR chunk with a "Stale Cookie" error cause indicates
+ one of a number of possible events:
+
+ A) That the association failed to completely setup before the State
+ Cookie issued by the sender was processed.
+
+ B) An old State Cookie was processed after setup completed.
+
+ C) An old State Cookie is received from someone that the receiver is
+ not interested in having an association with and the ABORT chunk
+ was lost.
+
+ When processing an ERROR chunk with a "Stale Cookie" error cause an
+ endpoint should first examine if an association is in the process of
+ being setup, i.e. the association is in the COOKIE-ECHOED state. In
+ all cases if the association is not in the COOKIE-ECHOED state, the
+ ERROR chunk should be silently discarded.
+
+ If the association is in the COOKIE-ECHOED state, the endpoint may
+ elect one of the following three alternatives.
+
+ 1) Send a new INIT chunk to the endpoint to generate a new State
+ Cookie and re-attempt the setup procedure.
+
+ 2) Discard the TCB and report to the upper layer the inability to
+ setup the association.
+
+ 3) Send a new INIT chunk to the endpoint, adding a Cookie
+ Preservative parameter requesting an extension to the lifetime of
+ the State Cookie. When calculating the time extension, an
+ implementation SHOULD use the RTT information measured based on
+ the previous COOKIE ECHO / ERROR exchange, and should add no more
+ than 1 second beyond the measured RTT, due to long State Cookie
+ lifetimes making the endpoint more subject to a replay attack.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 66]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+5.3 Other Initialization Issues
+
+5.3.1 Selection of Tag Value
+
+ Initiate Tag values should be selected from the range of 1 to 2**32 -
+ 1. It is very important that the Initiate Tag value be randomized to
+ help protect against "man in the middle" and "sequence number"
+ attacks. The methods described in [RFC1750] can be used for the
+ Initiate Tag randomization. Careful selection of Initiate Tags is
+ also necessary to prevent old duplicate packets from previous
+ associations being mistakenly processed as belonging to the current
+ association.
+
+ Moreover, the Verification Tag value used by either endpoint in a
+ given association MUST NOT change during the lifetime of an
+ association. A new Verification Tag value MUST be used each time the
+ endpoint tears-down and then re-establishes an association to the
+ same peer.
+
+6. User Data Transfer
+
+ Data transmission MUST only happen in the ESTABLISHED, SHUTDOWN-
+ PENDING, and SHUTDOWN-RECEIVED states. The only exception to this is
+ that DATA chunks are allowed to be bundled with an outbound COOKIE
+ ECHO chunk when in COOKIE-WAIT state.
+
+ DATA chunks MUST only be received according to the rules below in
+ ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-SENT. A DATA chunk received
+ in CLOSED is out of the blue and SHOULD be handled per 8.4. A DATA
+ chunk received in any other state SHOULD be discarded.
+
+ A SACK MUST be processed in ESTABLISHED, SHUTDOWN-PENDING, and
+ SHUTDOWN-RECEIVED. An incoming SACK MAY be processed in COOKIE-
+ ECHOED. A SACK in the CLOSED state is out of the blue and SHOULD be
+ processed according to the rules in 8.4. A SACK chunk received in
+ any other state SHOULD be discarded.
+
+
+ A SCTP receiver MUST be able to receive a minimum of 1500 bytes in
+ one SCTP packet. This means that a SCTP endpoint MUST NOT indicate
+ less than 1500 bytes in its Initial a_rwnd sent in the INIT or INIT
+ ACK.
+
+ For transmission efficiency, SCTP defines mechanisms for bundling of
+ small user messages and fragmentation of large user messages. The
+ following diagram depicts the flow of user messages through SCTP.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 67]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ In this section the term "data sender" refers to the endpoint that
+ transmits a DATA chunk and the term "data receiver" refers to the
+ endpoint that receives a DATA chunk. A data receiver will transmit
+ SACK chunks.
+
+ +--------------------------+
+ | User Messages |
+ +--------------------------+
+ SCTP user ^ |
+ ==================|==|=======================================
+ | v (1)
+ +------------------+ +--------------------+
+ | SCTP DATA Chunks | |SCTP Control Chunks |
+ +------------------+ +--------------------+
+ ^ | ^ |
+ | v (2) | v (2)
+ +--------------------------+
+ | SCTP packets |
+ +--------------------------+
+ SCTP ^ |
+ ===========================|==|===========================
+ | v
+ Connectionless Packet Transfer Service (e.g., IP)
+
+ Notes:
+
+ 1) When converting user messages into DATA chunks, an endpoint
+ will fragment user messages larger than the current association
+ path MTU into multiple DATA chunks. The data receiver will
+ normally reassemble the fragmented message from DATA chunks
+ before delivery to the user (see Section 6.9 for details).
+
+ 2) Multiple DATA and control chunks may be bundled by the sender
+ into a single SCTP packet for transmission, as long as the
+ final size of the packet does not exceed the current path MTU.
+ The receiver will unbundle the packet back into the original
+ chunks. Control chunks MUST come before DATA chunks in the
+ packet.
+
+ Figure 6: Illustration of User Data Transfer
+
+ The fragmentation and bundling mechanisms, as detailed in Sections
+ 6.9 and 6.10, are OPTIONAL to implement by the data sender, but they
+ MUST be implemented by the data receiver, i.e., an endpoint MUST
+ properly receive and process bundled or fragmented data.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 68]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+6.1 Transmission of DATA Chunks
+
+ This document is specified as if there is a single retransmission
+ timer per destination transport address, but implementations MAY have
+ a retransmission timer for each DATA chunk.
+
+ The following general rules MUST be applied by the data sender for
+ transmission and/or retransmission of outbound DATA chunks:
+
+ A) At any given time, the data sender MUST NOT transmit new data to
+ any destination transport address if its peer's rwnd indicates
+ that the peer has no buffer space (i.e. rwnd is 0, see Section
+ 6.2.1). However, regardless of the value of rwnd (including if it
+ is 0), the data sender can always have one DATA chunk in flight to
+ the receiver if allowed by cwnd (see rule B below). This rule
+ allows the sender to probe for a change in rwnd that the sender
+ missed due to the SACK having been lost in transit from the data
+ receiver to the data sender.
+
+ B) At any given time, the sender MUST NOT transmit new data to a
+ given transport address if it has cwnd or more bytes of data
+ outstanding to that transport address.
+
+ C) When the time comes for the sender to transmit, before sending new
+ DATA chunks, the sender MUST first transmit any outstanding DATA
+ chunks which are marked for retransmission (limited by the current
+ cwnd).
+
+ D) Then, the sender can send out as many new DATA chunks as Rule A
+ and Rule B above allow.
+
+ Multiple DATA chunks committed for transmission MAY be bundled in a
+ single packet. Furthermore, DATA chunks being retransmitted MAY be
+ bundled with new DATA chunks, as long as the resulting packet size
+ does not exceed the path MTU. A ULP may request that no bundling is
+ performed but this should only turn off any delays that a SCTP
+ implementation may be using to increase bundling efficiency. It does
+ not in itself stop all bundling from occurring (i.e. in case of
+ congestion or retransmission).
+
+ Before an endpoint transmits a DATA chunk, if any received DATA
+ chunks have not been acknowledged (e.g., due to delayed ack), the
+ sender should create a SACK and bundle it with the outbound DATA
+ chunk, as long as the size of the final SCTP packet does not exceed
+ the current MTU. See Section 6.2.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 69]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ IMPLEMENTATION NOTE: When the window is full (i.e., transmission is
+ disallowed by Rule A and/or Rule B), the sender MAY still accept send
+ requests from its upper layer, but MUST transmit no more DATA chunks
+ until some or all of the outstanding DATA chunks are acknowledged and
+ transmission is allowed by Rule A and Rule B again.
+
+ Whenever a transmission or retransmission is made to any address, if
+ the T3-rtx timer of that address is not currently running, the sender
+ MUST start that timer. If the timer for that address is already
+ running, the sender MUST restart the timer if the earliest (i.e.,
+ lowest TSN) outstanding DATA chunk sent to that address is being
+ retransmitted. Otherwise, the data sender MUST NOT restart the
+ timer.
+
+ When starting or restarting the T3-rtx timer, the timer value must be
+ adjusted according to the timer rules defined in Sections 6.3.2, and
+ 6.3.3.
+
+ Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+ 1 above the beginning TSN of the current send window.
+
+6.2 Acknowledgement on Reception of DATA Chunks
+
+ The SCTP endpoint MUST always acknowledge the reception of each valid
+ DATA chunk.
+
+ The guidelines on delayed acknowledgement algorithm specified in
+ Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an
+ acknowledgement SHOULD be generated for at least every second packet
+ (not every second DATA chunk) received, and SHOULD be generated
+ within 200 ms of the arrival of any unacknowledged DATA chunk. In
+ some situations it may be beneficial for an SCTP transmitter to be
+ more conservative than the algorithms detailed in this document
+ allow. However, an SCTP transmitter MUST NOT be more aggressive than
+ the following algorithms allow.
+
+ A SCTP receiver MUST NOT generate more than one SACK for every
+ incoming packet, other than to update the offered window as the
+ receiving application consumes new data.
+
+ IMPLEMENTATION NOTE: The maximum delay for generating an
+ acknowledgement may be configured by the SCTP administrator, either
+ statically or dynamically, in order to meet the specific timing
+ requirement of the protocol being carried.
+
+ An implementation MUST NOT allow the maximum delay to be configured
+ to be more than 500 ms. In other words an implementation MAY lower
+ this value below 500ms but MUST NOT raise it above 500ms.
+
+
+
+Stewart, et al. Standards Track [Page 70]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Acknowledgements MUST be sent in SACK chunks unless shutdown was
+ requested by the ULP in which case an endpoint MAY send an
+ acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge
+ the reception of multiple DATA chunks. See Section 3.3.4 for SACK
+ chunk format. In particular, the SCTP endpoint MUST fill in the
+ Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+ valid DATA chunk) it has received. Any received DATA chunks with TSN
+ greater than the value in the Cumulative TSN Ack field SHOULD also be
+ reported in the Gap Ack Block fields.
+
+ Note: The SHUTDOWN chunk does not contain Gap Ack Block fields.
+ Therefore, the endpoint should use a SACK instead of the SHUTDOWN
+ chunk to acknowledge DATA chunks received out of order .
+
+ When a packet arrives with duplicate DATA chunk(s) and with no new
+ DATA chunk(s), the endpoint MUST immediately send a SACK with no
+ delay. If a packet arrives with duplicate DATA chunk(s) bundled with
+ new DATA chunks, the endpoint MAY immediately send a SACK. Normally
+ receipt of duplicate DATA chunks will occur when the original SACK
+ chunk was lost and the peer's RTO has expired. The duplicate TSN
+ number(s) SHOULD be reported in the SACK as duplicate.
+
+ When an endpoint receives a SACK, it MAY use the Duplicate TSN
+ information to determine if SACK loss is occurring. Further use of
+ this data is for future study.
+
+ The data receiver is responsible for maintaining its receive buffers.
+ The data receiver SHOULD notify the data sender in a timely manner of
+ changes in its ability to receive data. How an implementation
+ manages its receive buffers is dependent on many factors (e.g.,
+ Operating System, memory management system, amount of memory, etc.).
+ However, the data sender strategy defined in Section 6.2.1 is based
+ on the assumption of receiver operation similar to the following:
+
+ A) At initialization of the association, the endpoint tells the
+ peer how much receive buffer space it has allocated to the
+ association in the INIT or INIT ACK. The endpoint sets a_rwnd
+ to this value.
+
+ B) As DATA chunks are received and buffered, decrement a_rwnd by
+ the number of bytes received and buffered. This is, in effect,
+ closing rwnd at the data sender and restricting the amount of
+ data it can transmit.
+
+ C) As DATA chunks are delivered to the ULP and released from the
+ receive buffers, increment a_rwnd by the number of bytes
+ delivered to the upper layer. This is, in effect, opening up
+ rwnd on the data sender and allowing it to send more data. The
+
+
+
+Stewart, et al. Standards Track [Page 71]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ data receiver SHOULD NOT increment a_rwnd unless it has
+ released bytes from its receive buffer. For example, if the
+ receiver is holding fragmented DATA chunks in a reassembly
+ queue, it should not increment a_rwnd.
+
+ D) When sending a SACK, the data receiver SHOULD place the current
+ value of a_rwnd into the a_rwnd field. The data receiver
+ SHOULD take into account that the data sender will not
+ retransmit DATA chunks that are acked via the Cumulative TSN
+ Ack (i.e., will drop from its retransmit queue).
+
+ Under certain circumstances, the data receiver may need to drop DATA
+ chunks that it has received but hasn't released from its receive
+ buffers (i.e., delivered to the ULP). These DATA chunks may have
+ been acked in Gap Ack Blocks. For example, the data receiver may be
+ holding data in its receive buffers while reassembling a fragmented
+ user message from its peer when it runs out of receive buffer space.
+ It may drop these DATA chunks even though it has acknowledged them in
+ Gap Ack Blocks. If a data receiver drops DATA chunks, it MUST NOT
+ include them in Gap Ack Blocks in subsequent SACKs until they are
+ received again via retransmission. In addition, the endpoint should
+ take into account the dropped data when calculating its a_rwnd.
+
+ An endpoint SHOULD NOT revoke a SACK and discard data. Only in
+ extreme circumstance should an endpoint use this procedure (such as
+ out of buffer space). The data receiver should take into account
+ that dropping data that has been acked in Gap Ack Blocks can result
+ in suboptimal retransmission strategies in the data sender and thus
+ in suboptimal performance.
+
+ The following example illustrates the use of delayed
+ acknowledgements:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 72]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Endpoint A Endpoint Z
+
+ {App sends 3 messages; strm 0}
+ DATA [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+ (Start T3-rtx timer)
+
+ DATA [TSN=8,Strm=0,Seq=4] ------------> (send ack)
+ /------- SACK [TSN Ack=8,block=0]
+ (cancel T3-rtx timer) <-----/
+
+ DATA [TSN=9,Strm=0,Seq=5] ------------> (ack delayed)
+ (Start T3-rtx timer)
+ ...
+ {App sends 1 message; strm 1}
+ (bundle SACK with DATA)
+ /----- SACK [TSN Ack=9,block=0] \
+ / DATA [TSN=6,Strm=1,Seq=2]
+ (cancel T3-rtx timer) <------/ (Start T3-rtx timer)
+
+ (ack delayed)
+ (send ack)
+ SACK [TSN Ack=6,block=0] -------------> (cancel T3-rtx timer)
+
+ Figure 7: Delayed Acknowledgment Example
+
+ If an endpoint receives a DATA chunk with no user data (i.e., the
+ Length field is set to 16) it MUST send an ABORT with error cause set
+ to "No User Data".
+
+ An endpoint SHOULD NOT send a DATA chunk with no user data part.
+
+6.2.1 Processing a Received SACK
+
+ Each SACK an endpoint receives contains an a_rwnd value. This value
+ represents the amount of buffer space the data receiver, at the time
+ of transmitting the SACK, has left of its total receive buffer space
+ (as specified in the INIT/INIT ACK). Using a_rwnd, Cumulative TSN
+ Ack and Gap Ack Blocks, the data sender can develop a representation
+ of the peer's receive buffer space.
+
+ One of the problems the data sender must take into account when
+ processing a SACK is that a SACK can be received out of order. That
+ is, a SACK sent by the data receiver can pass an earlier SACK and be
+ received first by the data sender. If a SACK is received out of
+ order, the data sender can develop an incorrect view of the peer's
+ receive buffer space.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 73]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Since there is no explicit identifier that can be used to detect
+ out-of-order SACKs, the data sender must use heuristics to determine
+ if a SACK is new.
+
+ An endpoint SHOULD use the following rules to calculate the rwnd,
+ using the a_rwnd value, the Cumulative TSN Ack and Gap Ack Blocks in
+ a received SACK.
+
+ A) At the establishment of the association, the endpoint initializes
+ the rwnd to the Advertised Receiver Window Credit (a_rwnd) the
+ peer specified in the INIT or INIT ACK.
+
+ B) Any time a DATA chunk is transmitted (or retransmitted) to a peer,
+ the endpoint subtracts the data size of the chunk from the rwnd of
+ that peer.
+
+ C) Any time a DATA chunk is marked for retransmission (via either
+ T3-rtx timer expiration (Section 6.3.3)or via fast retransmit
+ (Section 7.2.4)), add the data size of those chunks to the rwnd.
+
+ Note: If the implementation is maintaining a timer on each DATA
+ chunk then only DATA chunks whose timer expired would be marked
+ for retransmission.
+
+ D) Any time a SACK arrives, the endpoint performs the following:
+
+ i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+ Point, then drop the SACK. Since Cumulative TSN Ack is
+ monotonically increasing, a SACK whose Cumulative TSN Ack is
+ less than the Cumulative TSN Ack Point indicates an out-of-
+ order SACK.
+
+ ii) Set rwnd equal to the newly received a_rwnd minus the
+ number of bytes still outstanding after processing the
+ Cumulative TSN Ack and the Gap Ack Blocks.
+
+ iii) If the SACK is missing a TSN that was previously
+ acknowledged via a Gap Ack Block (e.g., the data receiver
+ reneged on the data), then mark the corresponding DATA chunk as
+ available for retransmit: Mark it as missing for fast
+ retransmit as described in Section 7.2.4 and if no retransmit
+ timer is running for the destination address to which the DATA
+ chunk was originally transmitted, then T3-rtx is started for
+ that destination address.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 74]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+6.3 Management of Retransmission Timer
+
+ An SCTP endpoint uses a retransmission timer T3-rtx to ensure data
+ delivery in the absence of any feedback from its peer. The duration
+ of this timer is referred to as RTO (retransmission timeout).
+
+ When an endpoint's peer is multi-homed, the endpoint will calculate a
+ separate RTO for each different destination transport address of its
+ peer endpoint.
+
+ The computation and management of RTO in SCTP follows closely how TCP
+ manages its retransmission timer. To compute the current RTO, an
+ endpoint maintains two state variables per destination transport
+ address: SRTT (smoothed round-trip time) and RTTVAR (round-trip time
+ variation).
+
+6.3.1 RTO Calculation
+
+ The rules governing the computation of SRTT, RTTVAR, and RTO are as
+ follows:
+
+ C1) Until an RTT measurement has been made for a packet sent to the
+ given destination transport address, set RTO to the protocol
+ parameter 'RTO.Initial'.
+
+ C2) When the first RTT measurement R is made, set SRTT <- R, RTTVAR
+ <- R/2, and RTO <- SRTT + 4 * RTTVAR.
+
+ C3) When a new RTT measurement R' is made, set
+
+ RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| SRTT
+ <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+
+ Note: The value of SRTT used in the update to RTTVAR is its value
+ before updating SRTT itself using the second assignment.
+
+ After the computation, update RTO <- SRTT + 4 * RTTVAR.
+
+ C4) When data is in flight and when allowed by rule C5 below, a new
+ RTT measurement MUST be made each round trip. Furthermore, new
+ RTT measurements SHOULD be made no more than once per round-trip
+ for a given destination transport address. There are two reasons
+ for this recommendation: First, it appears that measuring more
+ frequently often does not in practice yield any significant
+ benefit [ALLMAN99]; second, if measurements are made more often,
+ then the values of RTO.Alpha and RTO.Beta in rule C3 above should
+ be adjusted so that SRTT and RTTVAR still adjust to changes at
+ roughly the same rate (in terms of how many round trips it takes
+
+
+
+Stewart, et al. Standards Track [Page 75]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ them to reflect new values) as they would if making only one
+ measurement per round-trip and using RTO.Alpha and RTO.Beta as
+ given in rule C3. However, the exact nature of these adjustments
+ remains a research issue.
+
+ C5) Karn's algorithm: RTT measurements MUST NOT be made using packets
+ that were retransmitted (and thus for which it is ambiguous
+ whether the reply was for the first instance of the packet or a
+ later instance).
+
+ C6) Whenever RTO is computed, if it is less than RTO.Min seconds then
+ it is rounded up to RTO.Min seconds. The reason for this rule is
+ that RTOs that do not have a high minimum value are susceptible
+ to unnecessary timeouts [ALLMAN99].
+
+ C7) A maximum value may be placed on RTO provided it is at least
+ RTO.max seconds.
+
+ There is no requirement for the clock granularity G used for
+ computing RTT measurements and the different state variables, other
+ than:
+
+ G1) Whenever RTTVAR is computed, if RTTVAR = 0, then adjust RTTVAR <-
+ G.
+
+ Experience [ALLMAN99] has shown that finer clock granularities (<=
+ 100 msec) perform somewhat better than more coarse granularities.
+
+6.3.2 Retransmission Timer Rules
+
+ The rules for managing the retransmission timer are as follows:
+
+ R1) Every time a DATA chunk is sent to any address (including a
+ retransmission), if the T3-rtx timer of that address is not
+ running, start it running so that it will expire after the RTO of
+ that address. The RTO used here is that obtained after any
+ doubling due to previous T3-rtx timer expirations on the
+ corresponding destination address as discussed in rule E2 below.
+
+ R2) Whenever all outstanding data sent to an address have been
+ acknowledged, turn off the T3-rtx timer of that address.
+
+ R3) Whenever a SACK is received that acknowledges the DATA chunk with
+ the earliest outstanding TSN for that address, restart T3-rtx
+ timer for that address with its current RTO (if there is still
+ outstanding data on that address).
+
+
+
+
+
+Stewart, et al. Standards Track [Page 76]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ R4) Whenever a SACK is received missing a TSN that was previously
+ acknowledged via a Gap Ack Block, start T3-rtx for the
+ destination address to which the DATA chunk was originally
+ transmitted if it is not already running.
+
+ The following example shows the use of various timer rules (assuming
+ the receiver uses delayed acks).
+
+ Endpoint A Endpoint Z
+ {App begins to send}
+ Data [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+ (Start T3-rtx timer)
+ {App sends 1 message; strm 1}
+ (bundle ack with data)
+ DATA [TSN=8,Strm=0,Seq=4] ----\ /-- SACK [TSN Ack=7,Block=0]
+ \ / DATA [TSN=6,Strm=1,Seq=2]
+ \ / (Start T3-rtx timer)
+ \
+ / \
+ (Re-start T3-rtx timer) <------/ \--> (ack delayed)
+ (ack delayed)
+ {send ack}
+ SACK [TSN Ack=6,Block=0] --------------> (Cancel T3-rtx timer)
+ ..
+ (send ack)
+ (Cancel T3-rtx timer) <-------------- SACK [TSN Ack=8,Block=0]
+
+ Figure 8 - Timer Rule Examples
+
+6.3.3 Handle T3-rtx Expiration
+
+ Whenever the retransmission timer T3-rtx expires for a destination
+ address, do the following:
+
+ E1) For the destination address for which the timer expires, adjust
+ its ssthresh with rules defined in Section 7.2.3 and set the cwnd
+ <- MTU.
+
+ E2) For the destination address for which the timer expires, set RTO
+ <- RTO * 2 ("back off the timer"). The maximum value discussed
+ in rule C7 above (RTO.max) may be used to provide an upper bound
+ to this doubling operation.
+
+ E3) Determine how many of the earliest (i.e., lowest TSN) outstanding
+ DATA chunks for the address for which the T3-rtx has expired will
+ fit into a single packet, subject to the MTU constraint for the
+ path corresponding to the destination transport address to which
+ the retransmission is being sent (this may be different from the
+
+
+
+Stewart, et al. Standards Track [Page 77]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ address for which the timer expires [see Section 6.4]). Call
+ this value K. Bundle and retransmit those K DATA chunks in a
+ single packet to the destination endpoint.
+
+ E4) Start the retransmission timer T3-rtx on the destination address
+ to which the retransmission is sent, if rule R1 above indicates
+ to do so. The RTO to be used for starting T3-rtx should be the
+ one for the destination address to which the retransmission is
+ sent, which, when the receiver is multi-homed, may be different
+ from the destination address for which the timer expired (see
+ Section 6.4 below).
+
+ After retransmitting, once a new RTT measurement is obtained (which
+ can happen only when new data has been sent and acknowledged, per
+ rule C5, or for a measurement made from a HEARTBEAT [see Section
+ 8.3]), the computation in rule C3 is performed, including the
+ computation of RTO, which may result in "collapsing" RTO back down
+ after it has been subject to doubling (rule E2).
+
+ Note: Any DATA chunks that were sent to the address for which the
+ T3-rtx timer expired but did not fit in one MTU (rule E3 above),
+ should be marked for retransmission and sent as soon as cwnd allows
+ (normally when a SACK arrives).
+
+ The final rule for managing the retransmission timer concerns
+ failover (see Section 6.4.1):
+
+ F1) Whenever an endpoint switches from the current destination
+ transport address to a different one, the current retransmission
+ timers are left running. As soon as the endpoint transmits a
+ packet containing DATA chunk(s) to the new transport address,
+ start the timer on that transport address, using the RTO value of
+ the destination address to which the data is being sent, if rule
+ R1 indicates to do so.
+
+6.4 Multi-homed SCTP Endpoints
+
+ An SCTP endpoint is considered multi-homed if there are more than one
+ transport address that can be used as a destination address to reach
+ that endpoint.
+
+ Moreover, the ULP of an endpoint shall select one of the multiple
+ destination addresses of a multi-homed peer endpoint as the primary
+ path (see Sections 5.1.2 and 10.1 for details).
+
+ By default, an endpoint SHOULD always transmit to the primary path,
+ unless the SCTP user explicitly specifies the destination transport
+ address (and possibly source transport address) to use.
+
+
+
+Stewart, et al. Standards Track [Page 78]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,
+ etc.) to the same destination transport address from which it
+ received the DATA or control chunk to which it is replying. This
+ rule should also be followed if the endpoint is bundling DATA chunks
+ together with the reply chunk.
+
+ However, when acknowledging multiple DATA chunks received in packets
+ from different source addresses in a single SACK, the SACK chunk may
+ be transmitted to one of the destination transport addresses from
+ which the DATA or control chunks being acknowledged were received.
+
+ When a receiver of a duplicate DATA chunk sends a SACK to a multi-
+ homed endpoint it MAY be beneficial to vary the destination address
+ and not use the source address of the DATA chunk. The reason being
+ that receiving a duplicate from a multi-homed endpoint might indicate
+ that the return path (as specified in the source address of the DATA
+ chunk) for the SACK is broken.
+
+ Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+ retransmit a chunk to an active destination transport address that is
+ different from the last destination address to which the DATA chunk
+ was sent.
+
+ Retransmissions do not affect the total outstanding data count.
+ However, if the DATA chunk is retransmitted onto a different
+ destination address, both the outstanding data counts on the new
+ destination address and the old destination address to which the data
+ chunk was last sent shall be adjusted accordingly.
+
+6.4.1 Failover from Inactive Destination Address
+
+ Some of the transport addresses of a multi-homed SCTP endpoint may
+ become inactive due to either the occurrence of certain error
+ conditions (see Section 8.2) or adjustments from SCTP user.
+
+ When there is outbound data to send and the primary path becomes
+ inactive (e.g., due to failures), or where the SCTP user explicitly
+ requests to send data to an inactive destination transport address,
+ before reporting an error to its ULP, the SCTP endpoint should try to
+ send the data to an alternate active destination transport address if
+ one exists.
+
+ When retransmitting data, if the endpoint is multi-homed, it should
+ consider each source-destination address pair in its retransmission
+ selection policy. When retransmitting the endpoint should attempt to
+ pick the most divergent source-destination pair from the original
+ source-destination pair to which the packet was transmitted.
+
+
+
+
+Stewart, et al. Standards Track [Page 79]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Note: Rules for picking the most divergent source-destination pair
+ are an implementation decision and is not specified within this
+ document.
+
+6.5 Stream Identifier and Stream Sequence Number
+
+ Every DATA chunk MUST carry a valid stream identifier. If an
+ endpoint receives a DATA chunk with an invalid stream identifier, it
+ shall acknowledge the reception of the DATA chunk following the
+ normal procedure, immediately send an ERROR chunk with cause set to
+ "Invalid Stream Identifier" (see Section 3.3.10) and discard the DATA
+ chunk. The endpoint may bundle the ERROR chunk in the same packet as
+ the SACK as long as the ERROR follows the SACK.
+
+ The stream sequence number in all the streams shall start from 0 when
+ the association is established. Also, when the stream sequence
+ number reaches the value 65535 the next stream sequence number shall
+ be set to 0.
+
+6.6 Ordered and Unordered Delivery
+
+ Within a stream, an endpoint MUST deliver DATA chunks received with
+ the U flag set to 0 to the upper layer according to the order of
+ their stream sequence number. If DATA chunks arrive out of order of
+ their stream sequence number, the endpoint MUST hold the received
+ DATA chunks from delivery to the ULP until they are re-ordered.
+
+ However, an SCTP endpoint can indicate that no ordered delivery is
+ required for a particular DATA chunk transmitted within the stream by
+ setting the U flag of the DATA chunk to 1.
+
+ When an endpoint receives a DATA chunk with the U flag set to 1, it
+ must bypass the ordering mechanism and immediately deliver the data
+ to the upper layer (after re-assembly if the user data is fragmented
+ by the data sender).
+
+ This provides an effective way of transmitting "out-of-band" data in
+ a given stream. Also, a stream can be used as an "unordered" stream
+ by simply setting the U flag to 1 in all DATA chunks sent through
+ that stream.
+
+ IMPLEMENTATION NOTE: When sending an unordered DATA chunk, an
+ implementation may choose to place the DATA chunk in an outbound
+ packet that is at the head of the outbound transmission queue if
+ possible.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 80]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The 'Stream Sequence Number' field in a DATA chunk with U flag set to
+ 1 has no significance. The sender can fill it with arbitrary value,
+ but the receiver MUST ignore the field.
+
+ Note: When transmitting ordered and unordered data, an endpoint does
+ not increment its Stream Sequence Number when transmitting a DATA
+ chunk with U flag set to 1.
+
+6.7 Report Gaps in Received DATA TSNs
+
+ Upon the reception of a new DATA chunk, an endpoint shall examine the
+ continuity of the TSNs received. If the endpoint detects a gap in
+ the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack
+ Blocks immediately. The data receiver continues sending a SACK after
+ receipt of each SCTP packet that doesn't fill the gap.
+
+ Based on the Gap Ack Block from the received SACK, the endpoint can
+ calculate the missing DATA chunks and make decisions on whether to
+ retransmit them (see Section 6.2.1 for details).
+
+ Multiple gaps can be reported in one single SACK (see Section 3.3.4).
+
+ When its peer is multi-homed, the SCTP endpoint SHOULD always try to
+ send the SACK to the same destination address from which the last
+ DATA chunk was received.
+
+ Upon the reception of a SACK, the endpoint MUST remove all DATA
+ chunks which have been acknowledged by the SACK's Cumulative TSN Ack
+ from its transmit queue. The endpoint MUST also treat all the DATA
+ chunks with TSNs not included in the Gap Ack Blocks reported by the
+ SACK as "missing". The number of "missing" reports for each
+ outstanding DATA chunk MUST be recorded by the data sender in order
+ to make retransmission decisions. See Section 7.2.4 for details.
+
+ The following example shows the use of SACK to report a gap.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 81]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Endpoint A Endpoint Z
+ {App sends 3 messages; strm 0}
+ DATA [TSN=6,Strm=0,Seq=2] ---------------> (ack delayed)
+ (Start T3-rtx timer)
+
+ DATA [TSN=7,Strm=0,Seq=3] --------> X (lost)
+
+ DATA [TSN=8,Strm=0,Seq=4] ---------------> (gap detected,
+ immediately send ack)
+ /----- SACK [TSN Ack=6,Block=1,
+ / Strt=2,End=2]
+ <-----/
+ (remove 6 from out-queue,
+ and mark 7 as "1" missing report)
+
+ Figure 9 - Reporting a Gap using SACK
+
+ The maximum number of Gap Ack Blocks that can be reported within a
+ single SACK chunk is limited by the current path MTU. When a single
+ SACK can not cover all the Gap Ack Blocks needed to be reported due
+ to the MTU limitation, the endpoint MUST send only one SACK,
+ reporting the Gap Ack Blocks from the lowest to highest TSNs, within
+ the size limit set by the MTU, and leave the remaining highest TSN
+ numbers unacknowledged.
+
+6.8 Adler-32 Checksum Calculation
+
+ When sending an SCTP packet, the endpoint MUST strengthen the data
+ integrity of the transmission by including the Adler-32 checksum
+ value calculated on the packet, as described below.
+
+ After the packet is constructed (containing the SCTP common header
+ and one or more control or DATA chunks), the transmitter shall:
+
+ 1) Fill in the proper Verification Tag in the SCTP common header and
+ initialize the checksum field to 0's.
+
+ 2) Calculate the Adler-32 checksum of the whole packet, including the
+ SCTP common header and all the chunks. Refer to appendix B for
+ details of the Adler-32 algorithm. And,
+
+ 3) Put the resultant value into the checksum field in the common
+ header, and leave the rest of the bits unchanged.
+
+ When an SCTP packet is received, the receiver MUST first check the
+ Adler-32 checksum:
+
+ 1) Store the received Adler-32 checksum value aside,
+
+
+
+Stewart, et al. Standards Track [Page 82]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 2) Replace the 32 bits of the checksum field in the received SCTP
+ packet with all '0's and calculate an Adler-32 checksum value of
+ the whole received packet. And,
+
+ 3) Verify that the calculated Adler-32 checksum is the same as the
+ received Adler-32 checksum. If not, the receiver MUST treat the
+ packet as an invalid SCTP packet.
+
+ The default procedure for handling invalid SCTP packets is to
+ silently discard them.
+
+6.9 Fragmentation and Reassembly
+
+ An endpoint MAY support fragmentation when sending DATA chunks, but
+ MUST support reassembly when receiving DATA chunks. If an endpoint
+ supports fragmentation, it MUST fragment a user message if the size
+ of the user message to be sent causes the outbound SCTP packet size
+ to exceed the current MTU. If an implementation does not support
+ fragmentation of outbound user messages, the endpoint must return an
+ error to its upper layer and not attempt to send the user message.
+
+ IMPLEMENTATION NOTE: In this error case, the Send primitive
+ discussed in Section 10.1 would need to return an error to the upper
+ layer.
+
+ If its peer is multi-homed, the endpoint shall choose a size no
+ larger than the association Path MTU. The association Path MTU is
+ the smallest Path MTU of all destination addresses.
+
+ Note: Once a message is fragmented it cannot be re-fragmented.
+ Instead if the PMTU has been reduced, then IP fragmentation must be
+ used. Please see Section 7.3 for details of PMTU discovery.
+
+ When determining when to fragment, the SCTP implementation MUST take
+ into account the SCTP packet header as well as the DATA chunk
+ header(s). The implementation MUST also take into account the space
+ required for a SACK chunk if bundling a SACK chunk with the DATA
+ chunk.
+
+ Fragmentation takes the following steps:
+
+ 1) The data sender MUST break the user message into a series of DATA
+ chunks such that each chunk plus SCTP overhead fits into an IP
+ datagram smaller than or equal to the association Path MTU.
+
+ 2) The transmitter MUST then assign, in sequence, a separate TSN to
+ each of the DATA chunks in the series. The transmitter assigns
+ the same SSN to each of the DATA chunks. If the user indicates
+
+
+
+Stewart, et al. Standards Track [Page 83]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ that the user message is to be delivered using unordered delivery,
+ then the U flag of each DATA chunk of the user message MUST be set
+ to 1.
+
+ 3) The transmitter MUST also set the B/E bits of the first DATA chunk
+ in the series to '10', the B/E bits of the last DATA chunk in the
+ series to '01', and the B/E bits of all other DATA chunks in the
+ series to '00'.
+
+ An endpoint MUST recognize fragmented DATA chunks by examining the
+ B/E bits in each of the received DATA chunks, and queue the
+ fragmented DATA chunks for re-assembly. Once the user message is
+ reassembled, SCTP shall pass the re-assembled user message to the
+ specific stream for possible re-ordering and final dispatching.
+
+ Note: If the data receiver runs out of buffer space while still
+ waiting for more fragments to complete the re-assembly of the
+ message, it should dispatch part of its inbound message through a
+ partial delivery API (see Section 10), freeing some of its receive
+ buffer space so that the rest of the message may be received.
+
+6.10 Bundling
+
+ An endpoint bundles chunks by simply including multiple chunks in one
+ outbound SCTP packet. The total size of the resultant IP datagram,
+ including the SCTP packet and IP headers, MUST be less or equal to
+ the current Path MTU.
+
+ If its peer endpoint is multi-homed, the sending endpoint shall
+ choose a size no larger than the latest MTU of the current primary
+ path.
+
+ When bundling control chunks with DATA chunks, an endpoint MUST place
+ control chunks first in the outbound SCTP packet. The transmitter
+ MUST transmit DATA chunks within a SCTP packet in increasing order of
+ TSN.
+
+ Note: Since control chunks must be placed first in a packet and
+ since DATA chunks must be transmitted before SHUTDOWN or SHUTDOWN ACK
+ chunks, DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN ACK
+ chunks.
+
+ Partial chunks MUST NOT be placed in an SCTP packet.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 84]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ An endpoint MUST process received chunks in their order in the
+ packet. The receiver uses the chunk length field to determine the end
+ of a chunk and beginning of the next chunk taking account of the fact
+ that all chunks end on a 4 byte boundary. If the receiver detects a
+ partial chunk, it MUST drop the chunk.
+
+ An endpoint MUST NOT bundle INIT, INIT ACK or SHUTDOWN COMPLETE with
+ any other chunks.
+
+7. Congestion control
+
+ Congestion control is one of the basic functions in SCTP. For some
+ applications, it may be likely that adequate resources will be
+ allocated to SCTP traffic to assure prompt delivery of time-critical
+ data - thus it would appear to be unlikely, during normal operations,
+ that transmissions encounter severe congestion conditions. However
+ SCTP must operate under adverse operational conditions, which can
+ develop upon partial network failures or unexpected traffic surges.
+ In such situations SCTP must follow correct congestion control steps
+ to recover from congestion quickly in order to get data delivered as
+ soon as possible. In the absence of network congestion, these
+ preventive congestion control algorithms should show no impact on the
+ protocol performance.
+
+ IMPLEMENTATION NOTE: As far as its specific performance requirements
+ are met, an implementation is always allowed to adopt a more
+ conservative congestion control algorithm than the one defined below.
+
+ The congestion control algorithms used by SCTP are based on
+ [RFC2581]. This section describes how the algorithms defined in
+ RFC2581 are adapted for use in SCTP. We first list differences in
+ protocol designs between TCP and SCTP, and then describe SCTP's
+ congestion control scheme. The description will use the same
+ terminology as in TCP congestion control whenever appropriate.
+
+ SCTP congestion control is always applied to the entire association,
+ and not to individual streams.
+
+7.1 SCTP Differences from TCP Congestion control
+
+ Gap Ack Blocks in the SCTP SACK carry the same semantic meaning as
+ the TCP SACK. TCP considers the information carried in the SACK as
+ advisory information only. SCTP considers the information carried in
+ the Gap Ack Blocks in the SACK chunk as advisory. In SCTP, any DATA
+ chunk that has been acknowledged by SACK, including DATA that arrived
+ at the receiving end out of order, are not considered fully delivered
+ until the Cumulative TSN Ack Point passes the TSN of the DATA chunk
+ (i.e., the DATA chunk has been acknowledged by the Cumulative TSN Ack
+
+
+
+Stewart, et al. Standards Track [Page 85]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ field in the SACK). Consequently, the value of cwnd controls the
+ amount of outstanding data, rather than (as in the case of non-SACK
+ TCP) the upper bound between the highest acknowledged sequence number
+ and the latest DATA chunk that can be sent within the congestion
+ window. SCTP SACK leads to different implementations of fast-
+ retransmit and fast-recovery than non-SACK TCP. As an example see
+ [FALL96].
+
+ The biggest difference between SCTP and TCP, however, is multi-
+ homing. SCTP is designed to establish robust communication
+ associations between two endpoints each of which may be reachable by
+ more than one transport address. Potentially different addresses may
+ lead to different data paths between the two endpoints, thus ideally
+ one may need a separate set of congestion control parameters for each
+ of the paths. The treatment here of congestion control for multi-
+ homed receivers is new with SCTP and may require refinement in the
+ future. The current algorithms make the following assumptions:
+
+ o The sender usually uses the same destination address until being
+ instructed by the upper layer otherwise; however, SCTP may change
+ to an alternate destination in the event an address is marked
+ inactive (see Section 8.2). Also, SCTP may retransmit to a
+ different transport address than the original transmission.
+
+ o The sender keeps a separate congestion control parameter set for
+ each of the destination addresses it can send to (not each
+ source-destination pair but for each destination). The parameters
+ should decay if the address is not used for a long enough time
+ period.
+
+ o For each of the destination addresses, an endpoint does slow-start
+ upon the first transmission to that address.
+
+ Note: TCP guarantees in-sequence delivery of data to its upper-layer
+ protocol within a single TCP session. This means that when TCP
+ notices a gap in the received sequence number, it waits until the gap
+ is filled before delivering the data that was received with sequence
+ numbers higher than that of the missing data. On the other hand,
+ SCTP can deliver data to its upper-layer protocol even if there is a
+ gap in TSN if the Stream Sequence Numbers are in sequence for a
+ particular stream (i.e., the missing DATA chunks are for a different
+ stream) or if unordered delivery is indicated. Although this does
+ not affect cwnd, it might affect rwnd calculation.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 86]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+7.2 SCTP Slow-Start and Congestion Avoidance
+
+ The slow start and congestion avoidance algorithms MUST be used by an
+ endpoint to control the amount of data being injected into the
+ network. The congestion control in SCTP is employed in regard to the
+ association, not to an individual stream. In some situations it may
+ be beneficial for an SCTP sender to be more conservative than the
+ algorithms allow; however, an SCTP sender MUST NOT be more aggressive
+ than the following algorithms allow.
+
+ Like TCP, an SCTP endpoint uses the following three control variables
+ to regulate its transmission rate.
+
+ o Receiver advertised window size (rwnd, in bytes), which is set by
+ the receiver based on its available buffer space for incoming
+ packets.
+
+ Note: This variable is kept on the entire association.
+
+ o Congestion control window (cwnd, in bytes), which is adjusted by
+ the sender based on observed network conditions.
+
+ Note: This variable is maintained on a per-destination address
+ basis.
+
+ o Slow-start threshold (ssthresh, in bytes), which is used by the
+ sender to distinguish slow start and congestion avoidance phases.
+
+ Note: This variable is maintained on a per-destination address
+ basis.
+
+ SCTP also requires one additional control variable,
+ partial_bytes_acked, which is used during congestion avoidance phase
+ to facilitate cwnd adjustment.
+
+ Unlike TCP, an SCTP sender MUST keep a set of these control variables
+ cwnd, ssthresh and partial_bytes_acked for EACH destination address
+ of its peer (when its peer is multi-homed). Only one rwnd is kept
+ for the whole association (no matter if the peer is multi-homed or
+ has a single address).
+
+7.2.1 Slow-Start
+
+ Beginning data transmission into a network with unknown conditions or
+ after a sufficiently long idle period requires SCTP to probe the
+ network to determine the available capacity. The slow start
+ algorithm is used for this purpose at the beginning of a transfer, or
+ after repairing loss detected by the retransmission timer.
+
+
+
+Stewart, et al. Standards Track [Page 87]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o The initial cwnd before DATA transmission or after a sufficiently
+ long idle period MUST be <= 2*MTU.
+
+ o The initial cwnd after a retransmission timeout MUST be no more
+ than 1*MTU.
+
+ o The initial value of ssthresh MAY be arbitrarily high (for
+ example, implementations MAY use the size of the receiver
+ advertised window).
+
+ o Whenever cwnd is greater than zero, the endpoint is allowed to
+ have cwnd bytes of data outstanding on that transport address.
+
+ o When cwnd is less than or equal to ssthresh an SCTP endpoint MUST
+ use the slow start algorithm to increase cwnd (assuming the
+ current congestion window is being fully utilized). If an
+ incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be
+ increased by at most the lesser of 1) the total size of the
+ previously outstanding DATA chunk(s) acknowledged, and 2) the
+ destination's path MTU. This protects against the ACK-Splitting
+ attack outlined in [SAVAGE99].
+
+ In instances where its peer endpoint is multi-homed, if an endpoint
+ receives a SACK that advances its Cumulative TSN Ack Point, then it
+ should update its cwnd (or cwnds) apportioned to the destination
+ addresses to which it transmitted the acknowledged data. However if
+ the received SACK does not advance the Cumulative TSN Ack Point, the
+ endpoint MUST NOT adjust the cwnd of any of the destination
+ addresses.
+
+ Because an endpoint's cwnd is not tied to its Cumulative TSN Ack
+ Point, as duplicate SACKs come in, even though they may not advance
+ the Cumulative TSN Ack Point an endpoint can still use them to clock
+ out new data. That is, the data newly acknowledged by the SACK
+ diminishes the amount of data now in flight to less than cwnd; and so
+ the current, unchanged value of cwnd now allows new data to be sent.
+ On the other hand, the increase of cwnd must be tied to the
+ Cumulative TSN Ack Point advancement as specified above. Otherwise
+ the duplicate SACKs will not only clock out new data, but also will
+ adversely clock out more new data than what has just left the
+ network, during a time of possible congestion.
+
+ o When the endpoint does not transmit data on a given transport
+ address, the cwnd of the transport address should be adjusted to
+ max(cwnd/2, 2*MTU) per RTO.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 88]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+7.2.2 Congestion Avoidance
+
+ When cwnd is greater than ssthresh, cwnd should be incremented by
+ 1*MTU per RTT if the sender has cwnd or more bytes of data
+ outstanding for the corresponding transport address.
+
+ In practice an implementation can achieve this goal in the following
+ way:
+
+ o partial_bytes_acked is initialized to 0.
+
+ o Whenever cwnd is greater than ssthresh, upon each SACK arrival
+ that advances the Cumulative TSN Ack Point, increase
+ partial_bytes_acked by the total number of bytes of all new chunks
+ acknowledged in that SACK including chunks acknowledged by the new
+ Cumulative TSN Ack and by Gap Ack Blocks.
+
+ o When partial_bytes_acked is equal to or greater than cwnd and
+ before the arrival of the SACK the sender had cwnd or more bytes
+ of data outstanding (i.e., before arrival of the SACK, flightsize
+ was greater than or equal to cwnd), increase cwnd by MTU, and
+ reset partial_bytes_acked to (partial_bytes_acked - cwnd).
+
+ o Same as in the slow start, when the sender does not transmit DATA
+ on a given transport address, the cwnd of the transport address
+ should be adjusted to max(cwnd / 2, 2*MTU) per RTO.
+
+ o When all of the data transmitted by the sender has been
+ acknowledged by the receiver, partial_bytes_acked is initialized
+ to 0.
+
+7.2.3 Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), An
+ endpoint should do the following:
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = ssthresh
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform slow
+ start by:
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = 1*MTU
+
+
+
+
+
+Stewart, et al. Standards Track [Page 89]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ and assure that no more than one SCTP packet will be in flight for
+ that address until the endpoint receives acknowledgement for
+ successful delivery of data to that address.
+
+7.2.4 Fast Retransmit on Gap Reports
+
+ In the absence of data loss, an endpoint performs delayed
+ acknowledgement. However, whenever an endpoint notices a hole in the
+ arriving TSN sequence, it SHOULD start sending a SACK back every time
+ a packet arrives carrying data until the hole is filled.
+
+ Whenever an endpoint receives a SACK that indicates some TSN(s)
+ missing, it SHOULD wait for 3 further miss indications (via
+ subsequent SACK's) on the same TSN(s) before taking action with
+ regard to Fast Retransmit.
+
+ When the TSN(s) is reported as missing in the fourth consecutive
+ SACK, the data sender shall:
+
+ 1) Mark the missing DATA chunk(s) for retransmission,
+
+ 2) Adjust the ssthresh and cwnd of the destination address(es) to
+ which the missing DATA chunks were last sent, according to the
+ formula described in Section 7.2.3.
+
+ 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+ marked for retransmission will fit into a single packet, subject
+ to constraint of the path MTU of the destination transport address
+ to which the packet is being sent. Call this value K. Retransmit
+ those K DATA chunks in a single packet.
+
+ 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest
+ outstanding TSN number sent to that address, or the endpoint is
+ retransmitting the first outstanding DATA chunk sent to that
+ address.
+
+ Note: Before the above adjustments, if the received SACK also
+ acknowledges new DATA chunks and advances the Cumulative TSN Ack
+ Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2
+ must be applied first.
+
+ A straightforward implementation of the above keeps a counter for
+ each TSN hole reported by a SACK. The counter increments for each
+ consecutive SACK reporting the TSN hole. After reaching 4 and
+ starting the fast retransmit procedure, the counter resets to 0.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 90]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Because cwnd in SCTP indirectly bounds the number of outstanding
+ TSN's, the effect of TCP fast-recovery is achieved automatically with
+ no adjustment to the congestion control window size.
+
+7.3 Path MTU Discovery
+
+ [RFC1191] specifies "Path MTU Discovery", whereby an endpoint
+ maintains an estimate of the maximum transmission unit (MTU) along a
+ given Internet path and refrains from sending packets along that path
+ which exceed the MTU, other than occasional attempts to probe for a
+ change in the Path MTU (PMTU). RFC 1191 is thorough in its
+ discussion of the MTU discovery mechanism and strategies for
+ determining the current end-to-end MTU setting as well as detecting
+ changes in this value. [RFC1981] specifies the same mechanisms for
+ IPv6. An SCTP sender using IPv6 MUST use Path MTU Discovery unless
+ all packets are less than the minimum IPv6 MTU [RFC2460].
+
+ An endpoint SHOULD apply these techniques, and SHOULD do so on a
+ per-destination-address basis.
+
+ There are 4 ways in which SCTP differs from the description in RFC
+ 1191 of applying MTU discovery to TCP:
+
+ 1) SCTP associations can span multiple addresses. An endpoint MUST
+ maintain separate MTU estimates for each destination address of
+ its peer.
+
+ 2) Elsewhere in this document, when the term "MTU" is discussed, it
+ refers to the MTU associated with the destination address
+ corresponding to the context of the discussion.
+
+ 3) Unlike TCP, SCTP does not have a notion of "Maximum Segment Size".
+ Accordingly, the MTU for each destination address SHOULD be
+ initialized to a value no larger than the link MTU for the local
+ interface to which packets for that remote destination address
+ will be routed.
+
+ 4) Since data transmission in SCTP is naturally structured in terms
+ of TSNs rather than bytes (as is the case for TCP), the discussion
+ in Section 6.5 of RFC 1191 applies: When retransmitting an IP
+ datagram to a remote address for which the IP datagram appears too
+ large for the path MTU to that address, the IP datagram SHOULD be
+ retransmitted without the DF bit set, allowing it to possibly be
+ fragmented. Transmissions of new IP datagrams MUST have DF set.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 91]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 5) The sender should track an association PMTU which will be the
+ smallest PMTU discovered for all of the peer's destination
+ addresses. When fragmenting messages into multiple parts this
+ association PMTU should be used to calculate the size of each
+ fragment. This will allow retransmissions to be seamlessly sent
+ to an alternate address without encountering IP fragmentation.
+
+ Other than these differences, the discussion of TCP's use of MTU
+ discovery in RFCs 1191 and 1981 applies to SCTP on a per-
+ destination-address basis.
+
+ Note: For IPv6 destination addresses the DF bit does not exist,
+ instead the IP datagram must be fragmented as described in [RFC2460].
+
+8. Fault Management
+
+8.1 Endpoint Failure Detection
+
+ An endpoint shall keep a counter on the total number of consecutive
+ retransmissions to its peer (including retransmissions to all the
+ destination transport addresses of the peer if it is multi-homed).
+ If the value of this counter exceeds the limit indicated in the
+ protocol parameter 'Association.Max.Retrans', the endpoint shall
+ consider the peer endpoint unreachable and shall stop transmitting
+ any more data to it (and thus the association enters the CLOSED
+ state). In addition, the endpoint shall report the failure to the
+ upper layer, and optionally report back all outstanding user data
+ remaining in its outbound queue. The association is automatically
+ closed when the peer endpoint becomes unreachable.
+
+ The counter shall be reset each time a DATA chunk sent to that peer
+ endpoint is acknowledged (by the reception of a SACK), or a
+ HEARTBEAT-ACK is received from the peer endpoint.
+
+8.2 Path Failure Detection
+
+ When its peer endpoint is multi-homed, an endpoint should keep a
+ error counter for each of the destination transport addresses of the
+ peer endpoint.
+
+ Each time the T3-rtx timer expires on any address, or when a
+ HEARTBEAT sent to an idle address is not acknowledged within a RTO,
+ the error counter of that destination address will be incremented.
+ When the value in the error counter exceeds the protocol parameter
+ 'Path.Max.Retrans' of that destination address, the endpoint should
+ mark the destination transport address as inactive, and a
+ notification SHOULD be sent to the upper layer.
+
+
+
+
+Stewart, et al. Standards Track [Page 92]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ When an outstanding TSN is acknowledged or a HEARTBEAT sent to that
+ address is acknowledged with a HEARTBEAT ACK, the endpoint shall
+ clear the error counter of the destination transport address to which
+ the DATA chunk was last sent (or HEARTBEAT was sent). When the peer
+ endpoint is multi-homed and the last chunk sent to it was a
+ retransmission to an alternate address, there exists an ambiguity as
+ to whether or not the acknowledgement should be credited to the
+ address of the last chunk sent. However, this ambiguity does not
+ seem to bear any significant consequence to SCTP behavior. If this
+ ambiguity is undesirable, the transmitter may choose not to clear the
+ error counter if the last chunk sent was a retransmission.
+
+ Note: When configuring the SCTP endpoint, the user should avoid
+ having the value of 'Association.Max.Retrans' larger than the
+ summation of the 'Path.Max.Retrans' of all the destination addresses
+ for the remote endpoint. Otherwise, all the destination addresses
+ may become inactive while the endpoint still considers the peer
+ endpoint reachable. When this condition occurs, how the SCTP chooses
+ to function is implementation specific.
+
+ When the primary path is marked inactive (due to excessive
+ retransmissions, for instance), the sender MAY automatically transmit
+ new packets to an alternate destination address if one exists and is
+ active. If more than one alternate address is active when the
+ primary path is marked inactive only ONE transport address SHOULD be
+ chosen and used as the new destination transport address.
+
+8.3 Path Heartbeat
+
+ By default, an SCTP endpoint shall monitor the reachability of the
+ idle destination transport address(es) of its peer by sending a
+ HEARTBEAT chunk periodically to the destination transport
+ address(es).
+
+ A destination transport address is considered "idle" if no new chunk
+ which can be used for updating path RTT (usually including first
+ transmission DATA, INIT, COOKIE ECHO, HEARTBEAT etc.) and no
+ HEARTBEAT has been sent to it within the current heartbeat period of
+ that address. This applies to both active and inactive destination
+ addresses.
+
+ The upper layer can optionally initiate the following functions:
+
+ A) Disable heartbeat on a specific destination transport address of a
+ given association,
+
+ B) Change the HB.interval,
+
+
+
+
+Stewart, et al. Standards Track [Page 93]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ C) Re-enable heartbeat on a specific destination transport address of
+ a given association, and,
+
+ D) Request an on-demand HEARTBEAT on a specific destination transport
+ address of a given association.
+
+ The endpoint should increment the respective error counter of the
+ destination transport address each time a HEARTBEAT is sent to that
+ address and not acknowledged within one RTO.
+
+ When the value of this counter reaches the protocol parameter '
+ Path.Max.Retrans', the endpoint should mark the corresponding
+ destination address as inactive if it is not so marked, and may also
+ optionally report to the upper layer the change of reachability of
+ this destination address. After this, the endpoint should continue
+ HEARTBEAT on this destination address but should stop increasing the
+ counter.
+
+ The sender of the HEARTBEAT chunk should include in the Heartbeat
+ Information field of the chunk the current time when the packet is
+ sent out and the destination address to which the packet is sent.
+
+ IMPLEMENTATION NOTE: An alternative implementation of the heartbeat
+ mechanism that can be used is to increment the error counter variable
+ every time a HEARTBEAT is sent to a destination. Whenever a
+ HEARTBEAT ACK arrives, the sender SHOULD clear the error counter of
+ the destination that the HEARTBEAT was sent to. This in effect would
+ clear the previously stroked error (and any other error counts as
+ well).
+
+ The receiver of the HEARTBEAT should immediately respond with a
+ HEARTBEAT ACK that contains the Heartbeat Information field copied
+ from the received HEARTBEAT chunk.
+
+ Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT
+ should clear the error counter of the destination transport address
+ to which the HEARTBEAT was sent, and mark the destination transport
+ address as active if it is not so marked. The endpoint may
+ optionally report to the upper layer when an inactive destination
+ address is marked as active due to the reception of the latest
+ HEARTBEAT ACK. The receiver of the HEARTBEAT ACK must also clear the
+ association overall error count as well (as defined in section 8.1).
+
+ The receiver of the HEARTBEAT ACK should also perform an RTT
+ measurement for that destination transport address using the time
+ value carried in the HEARTBEAT ACK chunk.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 94]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ On an idle destination address that is allowed to heartbeat, a
+ HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that
+ destination address plus the protocol parameter 'HB.interval' , with
+ jittering of +/- 50%, and exponential back-off of the RTO if the
+ previous HEARTBEAT is unanswered.
+
+ A primitive is provided for the SCTP user to change the HB.interval
+ and turn on or off the heartbeat on a given destination address. The
+ heartbeat interval set by the SCTP user is added to the RTO of that
+ destination (including any exponential backoff). Only one heartbeat
+ should be sent each time the heartbeat timer expires (if multiple
+ destinations are idle). It is a implementation decision on how to
+ choose which of the candidate idle destinations to heartbeat to (if
+ more than one destination is idle).
+
+ Note: When tuning the heartbeat interval, there is a side effect that
+ SHOULD be taken into account. When this value is increased, i.e.
+ the HEARTBEAT takes longer, the detection of lost ABORT messages
+ takes longer as well. If a peer endpoint ABORTs the association for
+ any reason and the ABORT chunk is lost, the local endpoint will only
+ discover the lost ABORT by sending a DATA chunk or HEARTBEAT chunk
+ (thus causing the peer to send another ABORT). This must be
+ considered when tuning the HEARTBEAT timer. If the HEARTBEAT is
+ disabled only sending DATA to the association will discover a lost
+ ABORT from the peer.
+
+8.4 Handle "Out of the blue" Packets
+
+ An SCTP packet is called an "out of the blue" (OOTB) packet if it is
+ correctly formed, i.e., passed the receiver's Adler-32 check (see
+ Section 6.8), but the receiver is not able to identify the
+ association to which this packet belongs.
+
+ The receiver of an OOTB packet MUST do the following:
+
+ 1) If the OOTB packet is to or from a non-unicast address, silently
+ discard the packet. Otherwise,
+
+ 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
+ silently discard the OOTB packet and take no further action.
+ Otherwise,
+
+ 3) If the packet contains an INIT chunk with a Verification Tag set
+ to '0', process it as described in Section 5.1. Otherwise,
+
+ 4) If the packet contains a COOKIE ECHO in the first chunk, process
+ it as described in Section 5.1. Otherwise,
+
+
+
+
+Stewart, et al. Standards Track [Page 95]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
+ respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
+ When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
+ packet must fill in the Verification Tag field of the outbound
+ packet with the Verification Tag received in the SHUTDOWN ACK and
+ set the T-bit in the Chunk Flags to indicate that no TCB was
+ found. Otherwise,
+
+ 6) If the packet contains a SHUTDOWN COMPLETE chunk, the receiver
+ should silently discard the packet and take no further action.
+ Otherwise,
+
+ 7) If the packet contains a "Stale cookie" ERROR or a COOKIE ACK the
+ SCTP Packet should be silently discarded. Otherwise,
+
+ 8) The receiver should respond to the sender of the OOTB packet with
+ an ABORT. When sending the ABORT, the receiver of the OOTB packet
+ MUST fill in the Verification Tag field of the outbound packet
+ with the value found in the Verification Tag field of the OOTB
+ packet and set the T-bit in the Chunk Flags to indicate that no
+ TCB was found. After sending this ABORT, the receiver of the OOTB
+ packet shall discard the OOTB packet and take no further action.
+
+8.5 Verification Tag
+
+ The Verification Tag rules defined in this section apply when sending
+ or receiving SCTP packets which do not contain an INIT, SHUTDOWN
+ COMPLETE, COOKIE ECHO (see Section 5.1), ABORT or SHUTDOWN ACK chunk.
+ The rules for sending and receiving SCTP packets containing one of
+ these chunk types are discussed separately in Section 8.5.1.
+
+ When sending an SCTP packet, the endpoint MUST fill in the
+ Verification Tag field of the outbound packet with the tag value in
+ the Initiate Tag parameter of the INIT or INIT ACK received from its
+ peer.
+
+ When receiving an SCTP packet, the endpoint MUST ensure that the
+ value in the Verification Tag field of the received SCTP packet
+ matches its own Tag. If the received Verification Tag value does not
+ match the receiver's own tag value, the receiver shall silently
+ discard the packet and shall not process it any further except for
+ those cases listed in Section 8.5.1 below.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 96]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+8.5.1 Exceptions in Verification Tag Rules
+
+ A) Rules for packet carrying INIT:
+
+ - The sender MUST set the Verification Tag of the packet to 0.
+
+ - When an endpoint receives an SCTP packet with the Verification
+ Tag set to 0, it should verify that the packet contains only an
+ INIT chunk. Otherwise, the receiver MUST silently discard the
+ packet.
+
+ B) Rules for packet carrying ABORT:
+
+ - The endpoint shall always fill in the Verification Tag field of
+ the outbound packet with the destination endpoint's tag value
+ if it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the
+ endpoint MUST follow the procedure described in Section 8.4.
+
+ - The receiver MUST accept the packet if the Verification Tag
+ matches either its own tag, OR the tag of its peer. Otherwise,
+ the receiver MUST silently discard the packet and take no
+ further action.
+
+ C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+ - When sending a SHUTDOWN COMPLETE, if the receiver of the
+ SHUTDOWN ACK has a TCB then the destination endpoint's tag MUST
+ be used. Only where no TCB exists should the sender use the
+ Verification Tag from the SHUTDOWN ACK.
+
+ - The receiver of a SHUTDOWN COMPLETE shall accept the packet if
+ the Verification Tag field of the packet matches its own tag OR
+ it is set to its peer's tag and the T bit is set in the Chunk
+ Flags. Otherwise, the receiver MUST silently discard the packet
+ and take no further action. An endpoint MUST ignore the
+ SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
+
+ D) Rules for packet carrying a COOKIE ECHO
+
+ - When sending a COOKIE ECHO, the endpoint MUST use the value of
+ the Initial Tag received in the INIT ACK.
+
+ - The receiver of a COOKIE ECHO follows the procedures in Section
+ 5.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 97]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ E) Rules for packet carrying a SHUTDOWN ACK
+
+ - If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the
+ procedures in section 8.4 SHOULD be followed, in other words it
+ should be treated as an Out Of The Blue packet.
+
+9. Termination of Association
+
+ An endpoint should terminate its association when it exits from
+ service. An association can be terminated by either abort or
+ shutdown. An abort of an association is abortive by definition in
+ that any data pending on either end of the association is discarded
+ and not delivered to the peer. A shutdown of an association is
+ considered a graceful close where all data in queue by either
+ endpoint is delivered to the respective peers. However, in the case
+ of a shutdown, SCTP does not support a half-open state (like TCP)
+ wherein one side may continue sending data while the other end is
+ closed. When either endpoint performs a shutdown, the association on
+ each peer will stop accepting new data from its user and only deliver
+ data in queue at the time of sending or receiving the SHUTDOWN chunk.
+
+9.1 Abort of an Association
+
+ When an endpoint decides to abort an existing association, it shall
+ send an ABORT chunk to its peer endpoint. The sender MUST fill in
+ the peer's Verification Tag in the outbound packet and MUST NOT
+ bundle any DATA chunk with the ABORT.
+
+ An endpoint MUST NOT respond to any received packet that contains an
+ ABORT chunk (also see Section 8.4).
+
+ An endpoint receiving an ABORT shall apply the special Verification
+ Tag check rules described in Section 8.5.1.
+
+ After checking the Verification Tag, the receiving endpoint shall
+ remove the association from its record, and shall report the
+ termination to its upper layer.
+
+9.2 Shutdown of an Association
+
+ Using the SHUTDOWN primitive (see Section 10.1), the upper layer of
+ an endpoint in an association can gracefully close the association.
+ This will allow all outstanding DATA chunks from the peer of the
+ shutdown initiator to be delivered before the association terminates.
+
+ Upon receipt of the SHUTDOWN primitive from its upper layer, the
+ endpoint enters SHUTDOWN-PENDING state and remains there until all
+ outstanding data has been acknowledged by its peer. The endpoint
+
+
+
+Stewart, et al. Standards Track [Page 98]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ accepts no new data from its upper layer, but retransmits data to the
+ far end if necessary to fill gaps.
+
+ Once all its outstanding data has been acknowledged, the endpoint
+ shall send a SHUTDOWN chunk to its peer including in the Cumulative
+ TSN Ack field the last sequential TSN it has received from the peer.
+ It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT
+ state. If the timer expires, the endpoint must re-send the SHUTDOWN
+ with the updated last sequential TSN received from its peer.
+
+ The rules in Section 6.3 MUST be followed to determine the proper
+ timer value for T2-shutdown. To indicate any gaps in TSN, the
+ endpoint may also bundle a SACK with the SHUTDOWN chunk in the same
+ SCTP packet.
+
+ An endpoint should limit the number of retransmissions of the
+ SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.
+ If this threshold is exceeded the endpoint should destroy the TCB and
+ MUST report the peer endpoint unreachable to the upper layer (and
+ thus the association enters the CLOSED state). The reception of any
+ packet from its peer (i.e. as the peer sends all of its queued DATA
+ chunks) should clear the endpoint's retransmission count and restart
+ the T2-Shutdown timer, giving its peer ample opportunity to transmit
+ all of its queued DATA chunks that have not yet been sent.
+
+ Upon the reception of the SHUTDOWN, the peer endpoint shall
+
+ - enter the SHUTDOWN-RECEIVED state,
+
+ - stop accepting new data from its SCTP user
+
+ - verify, by checking the Cumulative TSN Ack field of the chunk,
+ that all its outstanding DATA chunks have been received by the
+ SHUTDOWN sender.
+
+ Once an endpoint as reached the SHUTDOWN-RECEIVED state it MUST NOT
+ send a SHUTDOWN in response to a ULP request, and should discard
+ subsequent SHUTDOWN chunks.
+
+ If there are still outstanding DATA chunks left, the SHUTDOWN
+ receiver shall continue to follow normal data transmission procedures
+ defined in Section 6 until all outstanding DATA chunks are
+ acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+ from its SCTP user.
+
+ While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
+ respond to each received packet containing one or more DATA chunk(s)
+ with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer. If
+
+
+
+Stewart, et al. Standards Track [Page 99]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ it has no more outstanding DATA chunks, the SHUTDOWN receiver shall
+ send a SHUTDOWN ACK and start a T2-shutdown timer of its own,
+ entering the SHUTDOWN-ACK-SENT state. If the timer expires, the
+ endpoint must re-send the SHUTDOWN ACK.
+
+ The sender of the SHUTDOWN ACK should limit the number of
+ retransmissions of the SHUTDOWN ACK chunk to the protocol parameter '
+ Association.Max.Retrans'. If this threshold is exceeded the endpoint
+ should destroy the TCB and may report the peer endpoint unreachable
+ to the upper layer (and thus the association enters the CLOSED
+ state).
+
+ Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall stop
+ the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its peer,
+ and remove all record of the association.
+
+ Upon reception of the SHUTDOWN COMPLETE chunk the endpoint will
+ verify that it is in SHUTDOWN-ACK-SENT state, if it is not the chunk
+ should be discarded. If the endpoint is in the SHUTDOWN-ACK-SENT
+ state the endpoint should stop the T2-shutdown timer and remove all
+ knowledge of the association (and thus the association enters the
+ CLOSED state).
+
+ An endpoint SHOULD assure that all its outstanding DATA chunks have
+ been acknowledged before initiating the shutdown procedure.
+
+ An endpoint should reject any new data request from its upper layer
+ if it is in SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED, or
+ SHUTDOWN-ACK-SENT state.
+
+ If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT
+ chunk (e.g., if the SHUTDOWN COMPLETE was lost) with source and
+ destination transport addresses (either in the IP addresses or in the
+ INIT chunk) that belong to this association, it should discard the
+ INIT chunk and retransmit the SHUTDOWN ACK chunk.
+
+ Note: Receipt of an INIT with the same source and destination IP
+ addresses as used in transport addresses assigned to an endpoint but
+ with a different port number indicates the initialization of a
+ separate association.
+
+ The sender of the INIT or COOKIE ECHO should respond to the receipt
+ of a SHUTDOWN-ACK with a stand-alone SHUTDOWN COMPLETE in an SCTP
+ packet with the Verification Tag field of its common header set to
+ the same tag that was received in the SHUTDOWN ACK packet. This is
+ considered an Out of the Blue packet as defined in Section 8.4. The
+ sender of the INIT lets T1-init continue running and remains in the
+
+
+
+
+Stewart, et al. Standards Track [Page 100]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ COOKIE-WAIT or COOKIE-ECHOED state. Normal T1-init timer expiration
+ will cause the INIT or COOKIE chunk to be retransmitted and thus
+ start a new association.
+
+ If a SHUTDOWN is received in COOKIE WAIT or COOKIE ECHOED states the
+ SHUTDOWN chunk SHOULD be silently discarded.
+
+ If an endpoint is in SHUTDOWN-SENT state and receives a SHUTDOWN
+ chunk from its peer, the endpoint shall respond immediately with a
+ SHUTDOWN ACK to its peer, and move into a SHUTDOWN-ACK-SENT state
+ restarting its T2-shutdown timer.
+
+ If an endpoint is in the SHUTDOWN-ACK-SENT state and receives a
+ SHUTDOWN ACK, it shall stop the T2-shutdown timer, send a SHUTDOWN
+ COMPLETE chunk to its peer, and remove all record of the association.
+
+10. Interface with Upper Layer
+
+ The Upper Layer Protocols (ULP) shall request for services by passing
+ primitives to SCTP and shall receive notifications from SCTP for
+ various events.
+
+ The primitives and notifications described in this section should be
+ used as a guideline for implementing SCTP. The following functional
+ description of ULP interface primitives is shown for illustrative
+ purposes. Different SCTP implementations may have different ULP
+ interfaces. However, all SCTPs must provide a certain minimum set of
+ services to guarantee that all SCTP implementations can support the
+ same protocol hierarchy.
+
+10.1 ULP-to-SCTP
+
+ The following sections functionally characterize a ULP/SCTP
+ interface. The notation used is similar to most procedure or
+ function calls in high level languages.
+
+ The ULP primitives described below specify the basic functions the
+ SCTP must perform to support inter-process communication. Individual
+ implementations must define their own exact format, and may provide
+ combinations or subsets of the basic functions in single calls.
+
+ A) Initialize
+
+ Format: INITIALIZE ([local port], [local eligible address list]) ->
+ local SCTP instance name
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 101]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ This primitive allows SCTP to initialize its internal data structures
+ and allocate necessary resources for setting up its operation
+ environment. Once SCTP is initialized, ULP can communicate directly
+ with other endpoints without re-invoking this primitive.
+
+ SCTP will return a local SCTP instance name to the ULP.
+
+ Mandatory attributes:
+
+ None.
+
+ Optional attributes:
+
+ The following types of attributes may be passed along with the
+ primitive:
+
+ o local port - SCTP port number, if ULP wants it to be specified;
+
+ o local eligible address list - An address list that the local SCTP
+ endpoint should bind. By default, if an address list is not
+ included, all IP addresses assigned to the host should be used by
+ the local endpoint.
+
+ IMPLEMENTATION NOTE: If this optional attribute is supported by an
+ implementation, it will be the responsibility of the implementation
+ to enforce that the IP source address field of any SCTP packets sent
+ out by this endpoint contains one of the IP addresses indicated in
+ the local eligible address list.
+
+ B) Associate
+
+ Format: ASSOCIATE(local SCTP instance name, destination transport addr,
+ outbound stream count)
+ -> association id [,destination transport addr list] [,outbound stream
+ count]
+
+ This primitive allows the upper layer to initiate an association to a
+ specific peer endpoint.
+
+ The peer endpoint shall be specified by one of the transport
+ addresses which defines the endpoint (see Section 1.4). If the local
+ SCTP instance has not been initialized, the ASSOCIATE is considered
+ an error.
+
+ An association id, which is a local handle to the SCTP association,
+ will be returned on successful establishment of the association. If
+ SCTP is not able to open an SCTP association with the peer endpoint,
+ an error is returned.
+
+
+
+Stewart, et al. Standards Track [Page 102]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Other association parameters may be returned, including the complete
+ destination transport addresses of the peer as well as the outbound
+ stream count of the local endpoint. One of the transport address
+ from the returned destination addresses will be selected by the local
+ endpoint as default primary path for sending SCTP packets to this
+ peer. The returned "destination transport addr list" can be used by
+ the ULP to change the default primary path or to force sending a
+ packet to a specific transport address.
+
+ IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a
+ blocking function call, the ASSOCIATE primitive can return
+ association parameters in addition to the association id upon
+ successful establishment. If ASSOCIATE primitive is implemented as a
+ non-blocking call, only the association id shall be returned and
+ association parameters shall be passed using the COMMUNICATION UP
+ notification.
+
+ Mandatory attributes:
+
+ o local SCTP instance name - obtained from the INITIALIZE operation.
+
+ o destination transport addr - specified as one of the transport
+ addresses of the peer endpoint with which the association is to be
+ established.
+
+ o outbound stream count - the number of outbound streams the ULP
+ would like to open towards this peer endpoint.
+
+ Optional attributes:
+
+ None.
+
+ C) Shutdown
+
+ Format: SHUTDOWN(association id)
+ -> result
+
+ Gracefully closes an association. Any locally queued user data will
+ be delivered to the peer. The association will be terminated only
+ after the peer acknowledges all the SCTP packets sent. A success
+ code will be returned on successful termination of the association.
+ If attempting to terminate the association results in a failure, an
+ error code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+
+
+
+Stewart, et al. Standards Track [Page 103]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Optional attributes:
+
+ None.
+
+ D) Abort
+
+ Format: ABORT(association id [, cause code])
+ -> result
+
+ Ungracefully closes an association. Any locally queued user data
+ will be discarded and an ABORT chunk is sent to the peer. A success
+ code will be returned on successful abortion of the association. If
+ attempting to abort the association results in a failure, an error
+ code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ Optional attributes:
+
+ o cause code - reason of the abort to be passed to the peer.
+
+ None.
+
+ E) Send
+
+ Format: SEND(association id, buffer address, byte count [,context]
+ [,stream id] [,life time] [,destination transport address]
+ [,unorder flag] [,no-bundle flag] [,payload protocol-id] )
+ -> result
+
+ This is the main method to send user data via SCTP.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o buffer address - the location where the user message to be
+ transmitted is stored;
+
+ o byte count - The size of the user data in number of bytes;
+
+ Optional attributes:
+
+ o context - an optional 32 bit integer that will be carried in the
+ sending failure notification to the ULP if the transportation of
+ this User Message fails.
+
+
+
+Stewart, et al. Standards Track [Page 104]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o stream id - to indicate which stream to send the data on. If not
+ specified, stream 0 will be used.
+
+ o life time - specifies the life time of the user data. The user
+ data will not be sent by SCTP after the life time expires. This
+ parameter can be used to avoid efforts to transmit stale user
+ messages. SCTP notifies the ULP if the data cannot be initiated
+ to transport (i.e. sent to the destination via SCTP's send
+ primitive) within the life time variable. However, the user data
+ will be transmitted if SCTP has attempted to transmit a chunk
+ before the life time expired.
+
+ IMPLEMENTATION NOTE: In order to better support the data lifetime
+ option, the transmitter may hold back the assigning of the TSN number
+ to an outbound DATA chunk to the last moment. And, for
+ implementation simplicity, once a TSN number has been assigned the
+ sender should consider the send of this DATA chunk as committed,
+ overriding any lifetime option attached to the DATA chunk.
+
+ o destination transport address - specified as one of the
+ destination transport addresses of the peer endpoint to which this
+ packet should be sent. Whenever possible, SCTP should use this
+ destination transport address for sending the packets, instead of
+ the current primary path.
+
+ o unorder flag - this flag, if present, indicates that the user
+ would like the data delivered in an unordered fashion to the peer
+ (i.e., the U flag is set to 1 on all DATA chunks carrying this
+ message).
+
+ o no-bundle flag - instructs SCTP not to bundle this user data with
+ other outbound DATA chunks. SCTP MAY still bundle even when this
+ flag is present, when faced with network congestion.
+
+ o payload protocol-id - A 32 bit unsigned integer that is to be
+ passed to the peer indicating the type of payload protocol data
+ being transmitted. This value is passed as opaque data by SCTP.
+
+ F) Set Primary
+
+ Format: SETPRIMARY(association id, destination transport address,
+ [source transport address] )
+ -> result
+
+ Instructs the local SCTP to use the specified destination transport
+ address as primary path for sending packets.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 105]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ The result of attempting this operation shall be returned. If the
+ specified destination transport address is not present in the
+ "destination transport address list" returned earlier in an associate
+ command or communication up notification, an error shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - specified as one of the transport
+ addresses of the peer endpoint, which should be used as primary
+ address for sending packets. This overrides the current primary
+ address information maintained by the local SCTP endpoint.
+
+ Optional attributes:
+
+ o source transport address - optionally, some implementations may
+ allow you to set the default source address placed in all outgoing
+ IP datagrams.
+
+ G) Receive
+
+ Format: RECEIVE(association id, buffer address, buffer size
+ [,stream id])
+ -> byte count [,transport address] [,stream id] [,stream sequence
+ number] [,partial flag] [,delivery number] [,payload protocol-id]
+
+ This primitive shall read the first user message in the SCTP in-queue
+ into the buffer specified by ULP, if there is one available. The
+ size of the message read, in bytes, will be returned. It may,
+ depending on the specific implementation, also return other
+ information such as the sender's address, the stream id on which it
+ is received, whether there are more messages available for retrieval,
+ etc. For ordered messages, their stream sequence number may also be
+ returned.
+
+ Depending upon the implementation, if this primitive is invoked when
+ no message is available the implementation should return an
+ indication of this condition or should block the invoking process
+ until data does become available.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+
+
+
+Stewart, et al. Standards Track [Page 106]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - to indicate which stream to receive the data on.
+
+ o stream sequence number - the stream sequence number assigned by
+ the sending SCTP peer.
+
+ o partial flag - if this returned flag is set to 1, then this
+ Receive contains a partial delivery of the whole message. When
+ this flag is set, the stream id and stream sequence number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this stream sequence
+ number.
+
+ o payload protocol-id - A 32 bit unsigned integer that is received
+ from the peer indicating the type of payload protocol of the
+ received data. This value is passed as opaque data by SCTP.
+
+ H) Status
+
+ Format: STATUS(association id)
+ -> status data
+
+ This primitive should return a data block containing the following
+ information:
+ association connection state,
+ destination transport address list,
+ destination transport address reachability states,
+ current receiver window size,
+ current congestion window sizes,
+ number of unacknowledged DATA chunks,
+ number of DATA chunks pending receipt,
+ primary path,
+ most recent SRTT on primary path,
+ RTO on primary path,
+ SRTT and RTO on other destination addresses, etc.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ Optional attributes:
+
+ None.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 107]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ I) Change Heartbeat
+
+ Format: CHANGEHEARTBEAT(association id, destination transport address,
+ new state [,interval])
+ -> result
+
+ Instructs the local endpoint to enable or disable heartbeat on the
+ specified destination transport address.
+
+ The result of attempting this operation shall be returned.
+
+ Note: Even when enabled, heartbeat will not take place if the
+ destination transport address is not idle.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - specified as one of the transport
+ addresses of the peer endpoint.
+
+ o new state - the new state of heartbeat for this destination
+ transport address (either enabled or disabled).
+
+ Optional attributes:
+
+ o interval - if present, indicates the frequency of the heartbeat if
+ this is to enable heartbeat on a destination transport address.
+ This value is added to the RTO of the destination transport
+ address. This value, if present, effects all destinations.
+
+ J) Request HeartBeat
+
+ Format: REQUESTHEARTBEAT(association id, destination transport
+ address)
+ -> result
+
+ Instructs the local endpoint to perform a HeartBeat on the specified
+ destination transport address of the given association. The returned
+ result should indicate whether the transmission of the HEARTBEAT
+ chunk to the destination address is successful.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - the transport address of the
+ association on which a heartbeat should be issued.
+
+
+
+Stewart, et al. Standards Track [Page 108]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ K) Get SRTT Report
+
+ Format: GETSRTTREPORT(association id, destination transport address)
+ -> srtt result
+
+ Instructs the local SCTP to report the current SRTT measurement on
+ the specified destination transport address of the given association.
+ The returned result can be an integer containing the most recent SRTT
+ in milliseconds.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - the transport address of the
+ association on which the SRTT measurement is to be reported.
+
+ L) Set Failure Threshold
+
+ Format: SETFAILURETHRESHOLD(association id, destination transport
+ address, failure threshold)
+ -> result
+
+ This primitive allows the local SCTP to customize the reachability
+ failure detection threshold 'Path.Max.Retrans' for the specified
+ destination address.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - the transport address of the
+ association on which the failure detection threshold is to be set.
+
+ o failure threshold - the new value of 'Path.Max.Retrans' for the
+ destination address.
+
+ M) Set Protocol Parameters
+
+ Format: SETPROTOCOLPARAMETERS(association id, [,destination transport
+ address,] protocol parameter list)
+ -> result
+
+ This primitive allows the local SCTP to customize the protocol
+ parameters.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 109]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o protocol parameter list - The specific names and values of the
+ protocol parameters (e.g., Association.Max.Retrans [see Section
+ 14]) that the SCTP user wishes to customize.
+
+ Optional attributes:
+
+ o destination transport address - some of the protocol parameters
+ may be set on a per destination transport address basis.
+
+ N) Receive unsent message
+
+ Format: RECEIVE_UNSENT(data retrieval id, buffer address, buffer size
+ [,stream id] [, stream sequence number] [,partial flag]
+ [,payload protocol-id])
+
+ o data retrieval id - The identification passed to the ULP in the
+ failure notification.
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - this is a return value that is set to indicate
+ which stream the data was sent to.
+
+ o stream sequence number - this value is returned indicating
+ the stream sequence number that was associated with the message.
+
+ o partial flag - if this returned flag is set to 1, then this
+ message is a partial delivery of the whole message. When
+ this flag is set, the stream id and stream sequence number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this stream sequence
+ number.
+
+ o payload protocol-id - The 32 bit unsigned integer that was sent to
+ be sent to the peer indicating the type of payload protocol of the
+ received data.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 110]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ O) Receive unacknowledged message
+
+ Format: RECEIVE_UNACKED(data retrieval id, buffer address, buffer size,
+ [,stream id] [, stream sequence number] [,partial flag]
+ [,payload protocol-id])
+
+ o data retrieval id - The identification passed to the ULP in the
+ failure notification.
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - this is a return value that is set to indicate which
+ stream the data was sent to.
+
+ o stream sequence number - this value is returned indicating the
+ stream sequence number that was associated with the message.
+
+ o partial flag - if this returned flag is set to 1, then this
+ message is a partial delivery of the whole message. When this
+ flag is set, the stream id and stream sequence number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this stream sequence
+ number.
+
+ o payload protocol-id - The 32 bit unsigned integer that was sent to
+ be sent to the peer indicating the type of payload protocol of the
+ received data.
+
+ P) Destroy SCTP instance
+
+ Format: DESTROY(local SCTP instance name)
+
+ o local SCTP instance name - this is the value that was passed to
+ the application in the initialize primitive and it indicates which
+ SCTP instance to be destroyed.
+
+10.2 SCTP-to-ULP
+
+ It is assumed that the operating system or application environment
+ provides a means for the SCTP to asynchronously signal the ULP
+ process. When SCTP does signal an ULP process, certain information
+ is passed to the ULP.
+
+
+
+
+Stewart, et al. Standards Track [Page 111]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ IMPLEMENTATION NOTE: In some cases this may be done through a
+ separate socket or error channel.
+
+ A) DATA ARRIVE notification
+
+ SCTP shall invoke this notification on the ULP when a user message is
+ successfully received and ready for retrieval.
+
+ The following may be optionally be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o stream id - to indicate which stream the data is received on.
+
+ B) SEND FAILURE notification
+
+ If a message can not be delivered SCTP shall invoke this notification
+ on the ULP.
+
+ The following may be optionally be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o data retrieval id - an identification used to retrieve unsent and
+ unacknowledged data.
+
+ o cause code - indicating the reason of the failure, e.g., size too
+ large, message life-time expiration, etc.
+
+ o context - optional information associated with this message (see D
+ in Section 10.1).
+
+ C) NETWORK STATUS CHANGE notification
+
+ When a destination transport address is marked inactive (e.g., when
+ SCTP detects a failure), or marked active (e.g., when SCTP detects a
+ recovery), SCTP shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o destination transport address - This indicates the destination
+ transport address of the peer endpoint affected by the change;
+
+ o new-status - This indicates the new status.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 112]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ D) COMMUNICATION UP notification
+
+ This notification is used when SCTP becomes ready to send or receive
+ user messages, or when a lost communication to an endpoint is
+ restored.
+
+ IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a
+ blocking function call, the association parameters are returned as a
+ result of the ASSOCIATE primitive itself. In that case,
+ COMMUNICATION UP notification is optional at the association
+ initiator's side.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o status - This indicates what type of event has occurred
+
+ o destination transport address list - the complete set of transport
+ addresses of the peer
+
+ o outbound stream count - the maximum number of streams allowed to
+ be used in this association by the ULP
+
+ o inbound stream count - the number of streams the peer endpoint has
+ requested with this association (this may not be the same number
+ as 'outbound stream count').
+
+ E) COMMUNICATION LOST notification
+
+ When SCTP loses communication to an endpoint completely (e.g., via
+ Heartbeats) or detects that the endpoint has performed an abort
+ operation, it shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o status - This indicates what type of event has occurred; The status
+ may indicate a failure OR a normal termination event
+ occurred in response to a shutdown or abort request.
+
+ The following may be passed with the notification:
+
+ o data retrieval id - an identification used to retrieve unsent and
+ unacknowledged data.
+
+ o last-acked - the TSN last acked by that peer endpoint;
+
+
+
+Stewart, et al. Standards Track [Page 113]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ o last-sent - the TSN last sent to that peer endpoint;
+
+ F) COMMUNICATION ERROR notification
+
+ When SCTP receives an ERROR chunk from its peer and decides to notify
+ its ULP, it can invoke this notification on the ULP.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o error info - this indicates the type of error and optionally some
+ additional information received through the ERROR chunk.
+
+ G) RESTART notification
+
+ When SCTP detects that the peer has restarted, it may send this
+ notification to its ULP.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ H) SHUTDOWN COMPLETE notification
+
+ When SCTP completes the shutdown procedures (section 9.2) this
+ notification is passed to the upper layer.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+11. Security Considerations
+
+11.1 Security Objectives
+
+ As a common transport protocol designed to reliably carry time-
+ sensitive user messages, such as billing or signaling messages for
+ telephony services, between two networked endpoints, SCTP has the
+ following security objectives.
+
+ - availability of reliable and timely data transport services
+ - integrity of the user-to-user information carried by SCTP
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 114]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+11.2 SCTP Responses To Potential Threats
+
+ SCTP may potentially be used in a wide variety of risk situations.
+ It is important for operator(s) of systems running SCTP to analyze
+ their particular situations and decide on the appropriate counter-
+ measures.
+
+ Operators of systems running SCTP should consult [RFC2196] for
+ guidance in securing their site.
+
+11.2.1 Countering Insider Attacks
+
+ The principles of [RFC2196] should be applied to minimize the risk of
+ theft of information or sabotage by insiders. Such procedures
+ include publication of security policies, control of access at the
+ physical, software, and network levels, and separation of services.
+
+11.2.2 Protecting against Data Corruption in the Network
+
+ Where the risk of undetected errors in datagrams delivered by the
+ lower layer transport services is considered to be too great,
+ additional integrity protection is required. If this additional
+ protection were provided in the application-layer, the SCTP header
+ would remain vulnerable to deliberate integrity attacks. While the
+ existing SCTP mechanisms for detection of packet replays are
+ considered sufficient for normal operation, stronger protections are
+ needed to protect SCTP when the operating environment contains
+ significant risk of deliberate attacks from a sophisticated
+ adversary.
+
+ In order to promote software code-reuse, to avoid re-inventing the
+ wheel, and to avoid gratuitous complexity to SCTP, the IP
+ Authentication Header [RFC2402] SHOULD be used when the threat
+ environment requires stronger integrity protections, but does not
+ require confidentiality.
+
+ A widely implemented BSD Sockets API extension exists for
+ applications to request IP security services, such as AH or ESP from
+ an operating system kernel. Applications can use such an API to
+ request AH whenever AH use is appropriate.
+
+11.2.3 Protecting Confidentiality
+
+ In most cases, the risk of breach of confidentiality applies to the
+ signaling data payload, not to the SCTP or lower-layer protocol
+ overheads. If that is true, encryption of the SCTP user data only
+ might be considered. As with the supplementary checksum service,
+ user data encryption MAY be performed by the SCTP user application.
+
+
+
+Stewart, et al. Standards Track [Page 115]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Alternately, the user application MAY use an implementation-specific
+ API to request that the IP Encapsulating Security Payload (ESP)
+ [RFC2406] be used to provide confidentiality and integrity.
+
+ Particularly for mobile users, the requirement for confidentiality
+ might include the masking of IP addresses and ports. In this case
+ ESP SHOULD be used instead of application-level confidentiality. If
+ ESP is used to protect confidentiality of SCTP traffic, an ESP
+ cryptographic transform that includes cryptographic integrity
+ protection MUST be used, because if there is a confidentiality threat
+ there will also be a strong integrity threat.
+
+ Whenever ESP is in use, application-level encryption is not generally
+ required.
+
+ Regardless of where confidentiality is provided, the ISAKMP [RFC2408]
+ and the Internet Key Exchange (IKE) [RFC2409] SHOULD be used for key
+ management.
+
+ Operators should consult [RFC2401] for more information on the
+ security services available at and immediately above the Internet
+ Protocol layer.
+
+11.2.4 Protecting against Blind Denial of Service Attacks
+
+ A blind attack is one where the attacker is unable to intercept or
+ otherwise see the content of data flows passing to and from the
+ target SCTP node. Blind denial of service attacks may take the form
+ of flooding, masquerade, or improper monopolization of services.
+
+11.2.4.1 Flooding
+
+ The objective of flooding is to cause loss of service and incorrect
+ behavior at target systems through resource exhaustion, interference
+ with legitimate transactions, and exploitation of buffer-related
+ software bugs. Flooding may be directed either at the SCTP node or
+ at resources in the intervening IP Access Links or the Internet.
+ Where the latter entities are the target, flooding will manifest
+ itself as loss of network services, including potentially the breach
+ of any firewalls in place.
+
+ In general, protection against flooding begins at the equipment
+ design level, where it includes measures such as:
+
+ - avoiding commitment of limited resources before determining that
+ the request for service is legitimate
+
+
+
+
+
+Stewart, et al. Standards Track [Page 116]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ - giving priority to completion of processing in progress over the
+ acceptance of new work
+
+ - identification and removal of duplicate or stale queued requests
+ for service.
+
+ - not responding to unexpected packets sent to non-unicast
+ addresses.
+
+ Network equipment should be capable of generating an alarm and log if
+ a suspicious increase in traffic occurs. The log should provide
+ information such as the identity of the incoming link and source
+ address(es) used which will help the network or SCTP system operator
+ to take protective measures. Procedures should be in place for the
+ operator to act on such alarms if a clear pattern of abuse emerges.
+
+ The design of SCTP is resistant to flooding attacks, particularly in
+ its use of a four-way start-up handshake, its use of a cookie to
+ defer commitment of resources at the responding SCTP node until the
+ handshake is completed, and its use of a Verification Tag to prevent
+ insertion of extraneous packets into the flow of an established
+ association.
+
+ The IP Authentication Header and Encapsulating Security Payload might
+ be useful in reducing the risk of certain kinds of denial of service
+ attacks."
+
+ The use of the Host Name feature in the INIT chunk could be used to
+ flood a target DNS server. A large backlog of DNS queries, resolving
+ the Host Name received in the INIT chunk to IP addresses, could be
+ accomplished by sending INIT's to multiple hosts in a given domain.
+ In addition, an attacker could use the Host Name feature in an
+ indirect attack on a third party by sending large numbers of INITs to
+ random hosts containing the host name of the target. In addition to
+ the strain on DNS resources, this could also result in large numbers
+ of INIT ACKs being sent to the target. One method to protect against
+ this type of attack is to verify that the IP addresses received from
+ DNS include the source IP address of the original INIT. If the list
+ of IP addresses received from DNS does not include the source IP
+ address of the INIT, the endpoint MAY silently discard the INIT.
+ This last option will not protect against the attack against the DNS.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 117]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+11.2.4.2 Blind Masquerade
+
+ Masquerade can be used to deny service in several ways:
+
+ - by tying up resources at the target SCTP node to which the
+ impersonated node has limited access. For example, the target
+ node may by policy permit a maximum of one SCTP association with
+ the impersonated SCTP node. The masquerading attacker may attempt
+ to establish an association purporting to come from the
+ impersonated node so that the latter cannot do so when it requires
+ it.
+
+ - by deliberately allowing the impersonation to be detected, thereby
+ provoking counter-measures which cause the impersonated node to be
+ locked out of the target SCTP node.
+
+ - by interfering with an established association by inserting
+ extraneous content such as a SHUTDOWN request.
+
+ SCTP reduces the risk of blind masquerade attacks through IP spoofing
+ by use of the four-way startup handshake. Man-in-the-middle
+ masquerade attacks are discussed in Section 11.3 below. Because the
+ initial exchange is memoryless, no lockout mechanism is triggered by
+ blind masquerade attacks. In addition, the INIT ACK containing the
+ State Cookie is transmitted back to the IP address from which it
+ received the INIT. Thus the attacker would not receive the INIT ACK
+ containing the State Cookie. SCTP protects against insertion of
+ extraneous packets into the flow of an established association by use
+ of the Verification Tag.
+
+ Logging of received INIT requests and abnormalities such as
+ unexpected INIT ACKs might be considered as a way to detect patterns
+ of hostile activity. However, the potential usefulness of such
+ logging must be weighed against the increased SCTP startup processing
+ it implies, rendering the SCTP node more vulnerable to flooding
+ attacks. Logging is pointless without the establishment of operating
+ procedures to review and analyze the logs on a routine basis.
+
+11.2.4.3 Improper Monopolization of Services
+
+ Attacks under this heading are performed openly and legitimately by
+ the attacker. They are directed against fellow users of the target
+ SCTP node or of the shared resources between the attacker and the
+ target node. Possible attacks include the opening of a large number
+ of associations between the attacker's node and the target, or
+ transfer of large volumes of information within a legitimately-
+ established association.
+
+
+
+
+Stewart, et al. Standards Track [Page 118]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Policy limits should be placed on the number of associations per
+ adjoining SCTP node. SCTP user applications should be capable of
+ detecting large volumes of illegitimate or "no-op" messages within a
+ given association and either logging or terminating the association
+ as a result, based on local policy.
+
+11.3 Protection against Fraud and Repudiation
+
+ The objective of fraud is to obtain services without authorization
+ and specifically without paying for them. In order to achieve this
+ objective, the attacker must induce the SCTP user application at the
+ target SCTP node to provide the desired service while accepting
+ invalid billing data or failing to collect it. Repudiation is a
+ related problem, since it may occur as a deliberate act of fraud or
+ simply because the repudiating party kept inadequate records of
+ service received.
+
+ Potential fraudulent attacks include interception and misuse of
+ authorizing information such as credit card numbers, blind masquerade
+ and replay, and man-in-the middle attacks which modify the packets
+ passing through a target SCTP association in real time.
+
+ The interception attack is countered by the confidentiality measures
+ discussed in Section 11.2.3 above.
+
+ Section 11.2.4.2 describes how SCTP is resistant to blind masquerade
+ attacks, as a result of the four-way startup handshake and the
+ Verification Tag. The Verification Tag and TSN together are
+ protections against blind replay attacks, where the replay is into an
+ existing association.
+
+ However, SCTP does not protect against man-in-the-middle attacks
+ where the attacker is able to intercept and alter the packets sent
+ and received in an association. For example, the INIT ACK will have
+ sufficient information sent on the wire for an adversary in the
+ middle to hijack an existing SCTP association. Where a significant
+ possibility of such attacks is seen to exist, or where possible
+ repudiation is an issue, the use of the IPSEC AH service is
+ recommended to ensure both the integrity and the authenticity of the
+ SCTP packets passed.
+
+ SCTP also provides no protection against attacks originating at or
+ beyond the SCTP node and taking place within the context of an
+ existing association. Prevention of such attacks should be covered
+ by appropriate security policies at the host site, as discussed in
+ Section 11.2.1.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 119]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+12. Recommended Transmission Control Block (TCB) Parameters
+
+ This section details a recommended set of parameters that should be
+ contained within the TCB for an implementation. This section is for
+ illustrative purposes and should not be deemed as requirements on an
+ implementation or as an exhaustive list of all parameters inside an
+ SCTP TCB. Each implementation may need its own additional parameters
+ for optimization.
+
+12.1 Parameters necessary for the SCTP instance
+
+ Associations: A list of current associations and mappings to the data
+ consumers for each association. This may be in the
+ form of a hash table or other implementation dependent
+ structure. The data consumers may be process
+ identification information such as file descriptors,
+ named pipe pointer, or table pointers dependent on how
+ SCTP is implemented.
+
+ Secret Key: A secret key used by this endpoint to compute the MAC.
+ This SHOULD be a cryptographic quality random number
+ with a sufficient length. Discussion in [RFC1750] can
+ be helpful in selection of the key.
+
+ Address List: The list of IP addresses that this instance has bound.
+ This information is passed to one's peer(s) in INIT and
+ INIT ACK chunks.
+
+ SCTP Port: The local SCTP port number the endpoint is bound to.
+
+12.2 Parameters necessary per association (i.e. the TCB)
+
+ Peer : Tag value to be sent in every packet and is received
+ Verification: in the INIT or INIT ACK chunk.
+ Tag :
+
+ My : Tag expected in every inbound packet and sent in the
+ Verification: INIT or INIT ACK chunk.
+ Tag :
+
+ State : A state variable indicating what state the association
+ : is in, i.e. COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,
+ : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
+ : SHUTDOWN-ACK-SENT.
+
+ Note: No "CLOSED" state is illustrated since if a
+ association is "CLOSED" its TCB SHOULD be removed.
+
+
+
+
+Stewart, et al. Standards Track [Page 120]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Peer : A list of SCTP transport addresses that the peer is
+ Transport : bound to. This information is derived from the INIT or
+ Address : INIT ACK and is used to associate an inbound packet
+ List : with a given association. Normally this information is
+ : hashed or keyed for quick lookup and access of the TCB.
+
+ Primary : This is the current primary destination transport
+ Path : address of the peer endpoint. It may also specify a
+ : source transport address on this endpoint.
+
+ Overall : The overall association error count.
+ Error Count :
+
+ Overall : The threshold for this association that if the Overall
+ Error : Error Count reaches will cause this association to be
+ Threshold : torn down.
+
+ Peer Rwnd : Current calculated value of the peer's rwnd.
+
+ Next TSN : The next TSN number to be assigned to a new DATA chunk.
+ : This is sent in the INIT or INIT ACK chunk to the peer
+ : and incremented each time a DATA chunk is assigned a
+ : TSN (normally just prior to transmit or during
+ : fragmentation).
+
+ Last Rcvd : This is the last TSN received in sequence. This value
+ TSN : is set initially by taking the peer's Initial TSN,
+ : received in the INIT or INIT ACK chunk, and
+ : subtracting one from it.
+
+ Mapping : An array of bits or bytes indicating which out of
+ Array : order TSN's have been received (relative to the
+ : Last Rcvd TSN). If no gaps exist, i.e. no out of order
+ : packets have been received, this array will be set to
+ : all zero. This structure may be in the form of a
+ : circular buffer or bit array.
+
+ Ack State : This flag indicates if the next received packet
+ : is to be responded to with a SACK. This is initialized
+ : to 0. When a packet is received it is incremented.
+ : If this value reaches 2 or more, a SACK is sent and the
+ : value is reset to 0. Note: This is used only when no
+ : DATA chunks are received out of order. When DATA chunks
+ : are out of order, SACK's are not delayed (see Section
+ : 6).
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 121]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Inbound : An array of structures to track the inbound streams.
+ Streams : Normally including the next sequence number expected
+ : and possibly the stream number.
+
+ Outbound : An array of structures to track the outbound streams.
+ Streams : Normally including the next sequence number to
+ : be sent on the stream.
+
+ Reasm Queue : A re-assembly queue.
+
+ Local : The list of local IP addresses bound in to this
+ Transport : association.
+ Address :
+ List :
+
+ Association : The smallest PMTU discovered for all of the
+ PMTU : peer's transport addresses.
+
+12.3 Per Transport Address Data
+
+ For each destination transport address in the peer's address list
+ derived from the INIT or INIT ACK chunk, a number of data elements
+ needs to be maintained including:
+
+ Error count : The current error count for this destination.
+
+ Error : Current error threshold for this destination i.e.
+ Threshold : what value marks the destination down if Error count
+ : reaches this value.
+
+ cwnd : The current congestion window.
+
+ ssthresh : The current ssthresh value.
+
+ RTO : The current retransmission timeout value.
+
+ SRTT : The current smoothed round trip time.
+
+ RTTVAR : The current RTT variation.
+
+ partial : The tracking method for increase of cwnd when in
+ bytes acked : congestion avoidance mode (see Section 6.2.2)
+
+ state : The current state of this destination, i.e. DOWN, UP,
+ : ALLOW-HB, NO-HEARTBEAT, etc.
+
+ PMTU : The current known path MTU.
+
+
+
+
+Stewart, et al. Standards Track [Page 122]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Per : A timer used by each destination.
+ Destination :
+ Timer :
+
+ RTO-Pending : A flag used to track if one of the DATA chunks sent to
+ this address is currently being used to compute a
+ RTT. If this flag is 0, the next DATA chunk sent to this
+ destination should be used to compute a RTT and this
+ flag should be set. Every time the RTT calculation
+ completes (i.e. the DATA chunk is SACK'd) clear this
+ flag.
+
+ last-time : The time this destination was last sent to. This can be
+ used : used to determine if a HEARTBEAT is needed.
+
+12.4 General Parameters Needed
+
+ Out Queue : A queue of outbound DATA chunks.
+
+ In Queue : A queue of inbound DATA chunks.
+
+13. IANA Considerations
+
+ This protocol will require port reservation like TCP for the use of
+ "well known" servers within the Internet. All current TCP ports
+ shall be automatically reserved in the SCTP port address space. New
+ requests should follow IANA's current mechanisms for TCP.
+
+ This protocol may also be extended through IANA in three ways:
+
+ -- through definition of additional chunk types,
+ -- through definition of additional parameter types, or
+ -- through definition of additional cause codes within
+ ERROR chunks
+
+ In the case where a particular ULP using SCTP desires to have its own
+ ports, the ULP should be responsible for registering with IANA for
+ getting its ports assigned.
+
+13.1 IETF-defined Chunk Extension
+
+ The definition and use of new chunk types is an integral part of
+ SCTP. Thus, new chunk types are assigned by IANA through an IETF
+ Consensus action as defined in [RFC2434].
+
+ The documentation for a new chunk code type must include the
+ following information:
+
+
+
+
+Stewart, et al. Standards Track [Page 123]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ a) A long and short name for the new chunk type;
+
+ b) A detailed description of the structure of the chunk, which MUST
+ conform to the basic structure defined in Section 3.2;
+
+ c) A detailed definition and description of intended use of each
+ field within the chunk, including the chunk flags if any;
+
+ d) A detailed procedural description of the use of the new chunk type
+ within the operation of the protocol.
+
+ The last chunk type (255) is reserved for future extension if
+ necessary.
+
+13.2 IETF-defined Chunk Parameter Extension
+
+ The assignment of new chunk parameter type codes is done through an
+ IETF Consensus action as defined in [RFC2434]. Documentation of the
+ chunk parameter MUST contain the following information:
+
+ a) Name of the parameter type.
+
+ b) Detailed description of the structure of the parameter field.
+ This structure MUST conform to the general type-length-value
+ format described in Section 3.2.1.
+
+ c) Detailed definition of each component of the parameter value.
+
+ d) Detailed description of the intended use of this parameter type,
+ and an indication of whether and under what circumstances multiple
+ instances of this parameter type may be found within the same
+ chunk.
+
+13.3 IETF-defined Additional Error Causes
+
+ Additional cause codes may be allocated in the range 11 to 65535
+ through a Specification Required action as defined in [RFC2434].
+ Provided documentation must include the following information:
+
+ a) Name of the error condition.
+
+ b) Detailed description of the conditions under which an SCTP
+ endpoint should issue an ERROR (or ABORT) with this cause code.
+
+ c) Expected action by the SCTP endpoint which receives an ERROR (or
+ ABORT) chunk containing this cause code.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 124]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ d) Detailed description of the structure and content of data fields
+ which accompany this cause code.
+
+ The initial word (32 bits) of a cause code parameter MUST conform to
+ the format shown in Section 3.3.10, i.e.:
+
+ -- first two bytes contain the cause code value
+ -- last two bytes contain length of the Cause Parameter.
+
+13.4 Payload Protocol Identifiers
+
+ Except for value 0 which is reserved by SCTP to indicate an
+ unspecified payload protocol identifier in a DATA chunk, SCTP will
+ not be responsible for standardizing or verifying any payload
+ protocol identifiers; SCTP simply receives the identifier from the
+ upper layer and carries it with the corresponding payload data.
+
+ The upper layer, i.e., the SCTP user, SHOULD standardize any specific
+ protocol identifier with IANA if it is so desired. The use of any
+ specific payload protocol identifier is out of the scope of SCTP.
+
+14. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.interval - 30 seconds
+
+ IMPLEMENTATION NOTE: The SCTP implementation may allow ULP to
+ customize some of these protocol parameters (see Section 10).
+
+ Note: RTO.Min SHOULD be set as recommended above.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 125]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+15. Acknowledgements
+
+ The authors wish to thank Mark Allman, R.J. Atkinson, Richard Band,
+ Scott Bradner, Steve Bellovin, Peter Butler, Ram Dantu, R.
+ Ezhirpavai, Mike Fisk, Sally Floyd, Atsushi Fukumoto, Matt Holdrege,
+ Henry Houh, Christian Huitema, Gary Lehecka, Jonathan Lee, David
+ Lehmann, John Loughney, Daniel Luan, Barry Nagelberg, Thomas Narten,
+ Erik Nordmark, Lyndon Ong, Shyamal Prasad, Kelvin Porter, Heinz
+ Prantner, Jarno Rajahalme, Raymond E. Reeves, Renee Revis, Ivan Arias
+ Rodriguez, A. Sankar, Greg Sidebottom, Brian Wyld, La Monte Yarroll,
+ and many others for their invaluable comments.
+
+16. Authors' Addresses
+
+ Randall R. Stewart
+ 24 Burning Bush Trail.
+ Crystal Lake, IL 60012
+ USA
+
+ Phone: +1-815-477-2127
+ EMail: rrs@cisco.com
+
+
+ Qiaobing Xie
+ Motorola, Inc.
+ 1501 W. Shure Drive, #2309
+ Arlington Heights, IL 60004
+ USA
+
+ Phone: +1-847-632-3028
+ EMail: qxie1@email.mot.com
+
+
+ Ken Morneault
+ Cisco Systems Inc.
+ 13615 Dulles Technology Drive
+ Herndon, VA. 20171
+ USA
+
+ Phone: +1-703-484-3323
+ EMail: kmorneau@cisco.com
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 126]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Chip Sharp
+ Cisco Systems Inc.
+ 7025 Kit Creek Road
+ Research Triangle Park, NC 27709
+ USA
+
+ Phone: +1-919-392-3121
+ EMail: chsharp@cisco.com
+
+
+ Hanns Juergen Schwarzbauer
+ SIEMENS AG
+ Hofmannstr. 51
+ 81359 Munich
+ Germany
+
+ Phone: +49-89-722-24236
+ EMail: HannsJuergen.Schwarzbauer@icn.siemens.de
+
+
+ Tom Taylor
+ Nortel Networks
+ 1852 Lorraine Ave.
+ Ottawa, Ontario
+ Canada K1H 6Z8
+
+ Phone: +1-613-736-0961
+ EMail: taylor@nortelnetworks.com
+
+
+ Ian Rytina
+ Ericsson Australia
+ 37/360 Elizabeth Street
+ Melbourne, Victoria 3000
+ Australia
+
+ Phone: +61-3-9301-6164
+ EMail: ian.rytina@ericsson.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 127]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ Malleswar Kalla
+ Telcordia Technologies
+ 3 Corporate Place
+ PYA-2J-341
+ Piscataway, NJ 08854
+ USA
+
+ Phone: +1-732-699-3728
+ EMail: mkalla@telcordia.com
+
+ Lixia Zhang
+ UCLA Computer Science Department
+ 4531G Boelter Hall
+ Los Angeles, CA 90095-1596
+ USA
+
+ Phone: +1-310-825-2695
+ EMail: lixia@cs.ucla.edu
+
+ Vern Paxson
+ ACIRI
+ 1947 Center St., Suite 600,
+ Berkeley, CA 94704-1198
+ USA
+
+ Phone: +1-510-666-2882
+ EMail: vern@aciri.org
+
+17. References
+
+ [RFC768] Postel, J. (ed.), "User Datagram Protocol", STD 6, RFC
+ 768, August 1980.
+
+ [RFC793] Postel, J. (ed.), "Transmission Control Protocol", STD 7,
+ RFC 793, September 1981.
+
+ [RFC1123] Braden, R., "Requirements for Internet hosts - application
+ and support", STD 3, RFC 1123, October 1989.
+
+ [RFC1191] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191,
+ November 1990.
+
+ [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC
+ 1700, October 1994.
+
+ [RFC1981] McCann, J., Deering, S. and J. Mogul, "Path MTU Discovery
+ for IP version 6", RFC 1981, August 1996.
+
+
+
+
+Stewart, et al. Standards Track [Page 128]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,
+ August 1996.
+
+ [RFC2026] Bradner, S., "The Internet Standards Process -- Revision
+ 3", BCP 9, RFC 2026, October 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the
+ Internet Protocol", RFC 2401, November 1998.
+
+ [RFC2402] Kent, S. and R. Atkinson, "IP Authentication Header", RFC
+ 2402, November 1998.
+
+ [RFC2406] Kent, S. and R. Atkinson, "IP Encapsulating Security
+ Payload (ESP)", RFC 2406, November 1998.
+
+ [RFC2408] Maughan, D., Schertler, M., Schneider, M. and J. Turner,
+ "Internet Security Association and Key Management
+ Protocol", RFC 2408, November 1998.
+
+ [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange
+ (IKE)", RFC 2409, November 1998.
+
+ [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
+ IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6
+ (IPv6) Specification", RFC 2460, December 1998.
+
+ [RFC2581] Allman, M., Paxson, V. and W. Stevens, "TCP Congestion
+ Control", RFC 2581, April 1999.
+
+18. Bibliography
+
+ [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+ Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+ [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP, Computer Communications Review,
+ V. 26 N. 3, July 1996, pp. 5-21.
+
+ [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for
+ Security", RFC 1750, December 1994.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 129]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, March 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management
+ Protocol", RFC 2522, March 1999.
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+ "TCP Congestion Control with a Misbehaving Receiver", ACM
+ Computer Communication Review, 29(5), October 1999.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 130]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+Appendix A: Explicit Congestion Notification
+
+ ECN (Ramakrishnan, K., Floyd, S., "Explicit Congestion Notification",
+ RFC 2481, January 1999) describes a proposed extension to IP that
+ details a method to become aware of congestion outside of datagram
+ loss. This is an optional feature that an implementation MAY choose
+ to add to SCTP. This appendix details the minor differences
+ implementers will need to be aware of if they choose to implement
+ this feature. In general RFC 2481 should be followed with the
+ following exceptions.
+
+ Negotiation:
+
+ RFC2481 details negotiation of ECN during the SYN and SYN-ACK stages
+ of a TCP connection. The sender of the SYN sets two bits in the TCP
+ flags, and the sender of the SYN-ACK sets only 1 bit. The reasoning
+ behind this is to assure both sides are truly ECN capable. For SCTP
+ this is not necessary. To indicate that an endpoint is ECN capable
+ an endpoint SHOULD add to the INIT and or INIT ACK chunk the TLV
+ reserved for ECN. This TLV contains no parameters, and thus has the
+ following format:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 32768 | Parameter Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ECN-Echo:
+
+ RFC 2481 details a specific bit for a receiver to send back in its
+ TCP acknowledgements to notify the sender of the Congestion
+ Experienced (CE) bit having arrived from the network. For SCTP this
+ same indication is made by including the ECNE chunk. This chunk
+ contains one data element, i.e. the lowest TSN associated with the IP
+ datagram marked with the CE bit, and looks as follows:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type=12 | Flags=00000000| Chunk Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Lowest TSN Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: The ECNE is considered a Control chunk.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 131]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ CWR:
+
+ RFC 2481 details a specific bit for a sender to send in the header of
+ its next outbound TCP segment to indicate to its peer that it has
+ reduced its congestion window. This is termed the CWR bit. For
+ SCTP the same indication is made by including the CWR chunk.
+ This chunk contains one data element, i.e. the TSN number that
+ was sent in the ECNE chunk. This element represents the lowest
+ TSN number in the datagram that was originally marked with the
+ CE bit.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type=13 | Flags=00000000| Chunk Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Lowest TSN Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: The CWR is considered a Control chunk.
+
+Appendix B Alder 32 bit checksum calculation
+
+ The Adler-32 checksum calculation given in this appendix is copied from
+ [RFC1950].
+
+ Adler-32 is composed of two sums accumulated per byte: s1 is the sum
+ of all bytes, s2 is the sum of all s1 values. Both sums are done
+ modulo 65521. s1 is initialized to 1, s2 to zero. The Adler-32
+ checksum is stored as s2*65536 + s1 in network byte order.
+
+ The following C code computes the Adler-32 checksum of a data buffer.
+ It is written for clarity, not for speed. The sample code is in the
+ ANSI C programming language. Non C users may find it easier to read
+ with these hints:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 132]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+ & Bitwise AND operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero bit(s)
+ at the left.
+ << Bitwise left shift operator. Left shift inserts zero
+ bit(s) at the right.
+ ++ "n++" increments the variable n.
+ % modulo operator: a % b is the remainder of a divided by b.
+ #define BASE 65521 /* largest prime smaller than 65536 */
+ /*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1]
+ and return the updated checksum. The Adler-32 checksum should be
+ initialized to 1.
+
+ Usage example:
+
+ unsigned long adler = 1L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = update_adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+ */
+ unsigned long update_adler32(unsigned long adler,
+ unsigned char *buf, int len)
+ {
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int n;
+
+ for (n = 0; n < len; n++) {
+ s1 = (s1 + buf[n]) % BASE;
+ s2 = (s2 + s1) % BASE;
+ }
+ return (s2 << 16) + s1;
+ }
+
+ /* Return the adler32 of the bytes buf[0..len-1] */
+ unsigned long adler32(unsigned char *buf, int len)
+ {
+ return update_adler32(1L, buf, len);
+ }
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 133]
+
+RFC 2960 Stream Control Transmission Protocol October 2000
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 134]
+
diff --git a/doc/rfc3257.txt b/doc/rfc3257.txt
new file mode 100644
index 0000000..c2df92b
--- /dev/null
+++ b/doc/rfc3257.txt
@@ -0,0 +1,731 @@
+
+
+
+
+
+
+Network Working Group L. Coene
+Request for Comments: 3257 Siemens
+Category: Informational April 2002
+
+
+ Stream Control Transmission Protocol Applicability Statement
+
+Status of this Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+Abstract
+
+ This document describes the applicability of the Stream Control
+ Transmission Protocol (SCTP). It also contrasts SCTP with the two
+ dominant transport protocols, User Datagram Protocol (UDP) &
+ Transmission Control Protocol (TCP), and gives some guidelines for
+ when best to use SCTP and when not best to use SCTP.
+
+Table of contents
+
+ 1. Introduction .................................................. 2
+ 1.1 Terminology .................................................. 2
+ 2 Transport protocols ............................................ 2
+ 2.1 TCP service model ............................................ 2
+ 2.2 SCTP service model ........................................... 3
+ 2.3 UDP service model ............................................ 4
+ 3 SCTP Multihoming issues ........................................ 4
+ 4 SCTP Network Address Translators (NAT) issues [RFC2663] ........ 5
+ 5 Security Considerations ........................................ 6
+ 5.1 Security issues with TCP ..................................... 6
+ 5.2 Security issues with SCTP .................................... 7
+ 5.3 Security issues with both TCP and SCTP ....................... 8
+ 6 References and related work .................................... 9
+ 7 Acknowledgments ................................................ 10
+ Appendix A: Major functions provided by SCTP ..................... 11
+ Editor's Address ................................................. 12
+ Full Copyright Statement ......................................... 13
+
+
+
+
+
+
+
+Coene Informational [Page 1]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+1 Introduction
+
+ SCTP is a reliable transport protocol [RFC2960], which along with TCP
+ [RFC793], RTP [RFC1889], and UDP [RFC768], provides transport-layer
+ services for upper layer protocols and services. UDP, RTP, TCP, and
+ SCTP are currently the IETF standards-track transport-layer
+ protocols. Each protocol has a domain of applicability and services
+ it provides, albeit with some overlaps.
+
+ By clarifying the situations where the functionality of these
+ protocols are applicable, this document can guide implementers and
+ protocol designers in selecting which protocol to use.
+
+ Special attention is given to services SCTP provides which would make
+ a decision to use SCTP the right one.
+
+ Major functions provided by SCTP can be found in Appendix A.
+
+1.1 Terminology
+
+ The following terms are commonly identified in this work:
+
+ Association: SCTP connection between two endpoints.
+
+ Transport address: A combination of IP address and SCTP port number.
+
+ Upper layer: The user of the SCTP protocol, which may be an
+ adaptation layer, a session layer protocol, or the user application
+ directly.
+
+ Multihoming: Assigning more than one IP network interface to a single
+ endpoint.
+
+2 Transport protocols
+
+2.1 TCP service model
+
+ TCP is a connection-oriented (a.k.a., session-oriented) transport
+ protocol. This means that it requires both the establishment of a
+ connection prior to the exchange of application data and a connection
+ tear-down to release system resources after the completion of data
+ transfer.
+
+ TCP is currently the most widely used connection-oriented transport
+ protocol for the Internet.
+
+
+
+
+
+
+Coene Informational [Page 2]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ TCP provides the upper layer with the following transport services:
+
+ - data reliability;
+
+ - data sequence preservation; and
+
+ - flow and congestion control.
+
+2.2 SCTP service model
+
+ SCTP is also connection-oriented and provides all the transport
+ services that TCP provides. Many Internet applications therefore
+ should find that either TCP or SCTP will meet their transport
+ requirements. Note, for applications conscious about processing
+ cost, there might be a difference in processing cost associated with
+ running SCTP with only a single ordered stream and one address pair
+ in comparison to running TCP.
+
+ However, SCTP has some additional capabilities that TCP lacks and
+ This can make SCTP a better choice for some applications and
+ environments:
+
+ - multi-streams support:
+
+ SCTP supports the delivery of multiple independent user message
+ streams within a single SCTP association. This capability, when
+ properly used, can alleviate the so-called head-of-line-blocking
+ problem caused by the strict sequence delivery constraint imposed to
+ the user data by TCP.
+
+ This can be particularly useful for applications that need to
+ exchange multiple, logically separate message streams between two
+ endpoints.
+
+ - multi-homing support:
+
+ SCTP provides transparent support for communications between two
+ endpoints of which one or both is multi-homed.
+
+ SCTP provides monitoring of the reachability of the addresses on the
+ remote endpoint and in the case of failure can transparently failover
+ from the primary address to an alternate address, without upper layer
+ intervention.
+
+
+
+
+
+
+
+
+Coene Informational [Page 3]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ This capability can be used to build redundant paths between two SCTP
+ endpoints and can be particularly useful for applications that seek
+ transport-level fault tolerance.
+
+ Achieving path redundancy between two SCTP endpoints normally
+ requires that the two endpoints being equipped with multiple
+ interfaces assigned with multiple addresses and that routing is
+ configured appropriately (see Section 3).
+
+ - preservation of message boundaries:
+
+ SCTP preserves application messages boundaries. This is useful when
+ the application data is not a continuous byte stream but comes in
+ logical chunks that the receiver handles separately.
+
+ In contrast, TCP offers a reliable data stream that has no indication
+ of what an application may consider logical chunks of the data.
+
+ - unordered reliable message delivery:
+
+ SCTP supports the transportation of user messages that have no
+ application-specified order, yet need guaranteed reliable delivery.
+
+ Applications that need to send un-ordered reliable messages or prefer
+ using their own message sequencing and ordering mechanisms may find
+ this SCTP capability useful.
+
+2.3 UDP Service model
+
+ UDP is connectionless. This means that applications that use UDP do
+ not need to perform connection establishment or tear-down.
+
+ As transport services to its upper layer, UDP provides only:
+
+ - best-effort data delivery, and
+
+ - preservation of message boundaries.
+
+ Applications that do not require a reliable transfer of more than a
+ packet's worth of data will find UDP adequate. Some transaction-
+ based applications fall into this category.
+
+3 SCTP Multihoming Issues
+
+ SCTP provides transport-layer support for multihoming. Multihoming
+ has the potential of providing additional robustness against network
+ failures. In some applications, this may be extremely important, for
+ example, in signaling transport of PSTN signaling messages [RFC2719].
+
+
+
+Coene Informational [Page 4]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ It should be noted that SCTP multihoming support only deals with
+ communication between two endpoints of which one or both is assigned
+ with multiple IP addresses on possibly multiple network interfaces.
+ It does NOT deal with communication ends that contain multiple
+ endpoints (i.e., clustered endpoints) that can switch over to an
+ alternate endpoint in case of failure of the original endpoint.
+
+ Generally, for truly fault resilient communication between two end-
+ points, the multihoming feature needs more than one IP network
+ interface for each endpoint. The number of paths used is the minimum
+ of network interfaces used by any of the endpoints. When an endpoint
+ selects its source address, careful consideration must be taken. If
+ the same source address is always used, then it is possible that the
+ endpoint will be subject to the same single point of failure. When
+ the endpoint chooses a source address, it should always select the
+ source address of the packet to correspond to the IP address of the
+ Network interface where the packet will be emitted subject to the
+ binding address constraint. The binding address constraint is, put
+ simply, that the endpoint must never choose a source address that is
+ not part of the association i.e., the peer endpoint must recognize
+ any source address used as being part of the association.
+
+ The availability of the association will benefit greatly from having
+ multiple addresses bound to the association endpoint when the
+ endpoint is on a multi-homed host.
+
+4 SCTP Network Address Translators (NAT) issues [RFC2663]
+
+ When two endpoints are to setup an SCTP association and one (or both)
+ of them is behind a NAT (i.e., it does not have any publicly
+ available network addresses), the endpoint(s) behind the NAT should
+ consider one of the following options:
+
+ (1) When single homed sessions are to be used, no transport addresses
+ should be sent in the INIT or INIT ACK chunk(Refer to section 3.3 of
+ RFC2960 for chunk definitions). This will force the endpoint that
+ receives this initiation message to use the source address in the IP
+ header as the only destination address for this association. This
+ method can be used for a NAT, but any multi-homing configuration at
+ the endpoint that is behind the NAT will not be visible to its peer,
+ and thus not be taken advantage of. See figure 1.
+
+
+
+
+
+
+
+
+
+
+Coene Informational [Page 5]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ +-------+ +---------+ *~~~~~~~~~~* +------+
+ |Host A | | NAT | * Cloud * |Host B|
+ | 10.2 +--|10.1|2.1 |----|--------------|---------+ 1.2 |
+ | | | | | * * | |
+ +-------+ +---------+ *~~~~~~~~~~* +------+
+
+ Fig 1: SCTP through NAT without multihoming
+
+ For multihoming the NAT must have a public IP address for each
+ represented internal IP address. The host can preconfigure an IP
+ address that the NAT can substitute, or, the NAT can have internal
+ Application Layer Gateway (ALG) which will intelligently translate
+ the IP addresses in the INIT and INIT ACK chunks. See Figure 2.
+
+ If Network Address Port Translation is used with a multihomed SCTP
+ endpoint, then any port translation must be applied on a per-
+ association basis such that an SCTP endpoint continues to receive the
+ same port number for all messages within a given association.
+
+ +-------+ +----------+ *~~~~~~~~~~* +------+
+ |Host A | | NAT | * Cloud * |Host B|
+ | 10.2 +---+ 10.1|5.2 +-----+ 1.1<+->3.1--+---------+ 1.2 |
+ | 11.2 +---+ 11.1|6.2 | | +->4.2--+---------+ 2.2 |
+ | | | | * * | |
+ +-------+ +----------+ *~~~~~~~~~* +------+
+
+ Fig 2: SCTP through NAT with multihoming
+
+ (2) Another alternative is to use the hostname feature and DNS to
+ resolve the addresses. The hostname is included in the INIT of the
+ association or in the INIT ACK. The hostname must be resolved by DNS
+ before the association is completely set up. There are special
+ issues regarding NAT and DNS, refer to RFC2694 for details.
+
+5 Security Considerations
+
+ In this section, some relevant security issues found in the
+ deployment of the connection-oriented transport protocols will be
+ discussed.
+
+5.1 Security issues with TCP
+
+ Some TCP implementations have been known to be vulnerable to blind
+ denial of service attacks, i.e., attacks that had been executed by an
+ attacker that could not see most of the traffic to or from the target
+ host.
+
+
+
+
+
+Coene Informational [Page 6]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ The attacker would send a large number of connection establishment
+ requests (TCP-SYN packets) to the attacked target, possibly from
+ faked IP source addresses. The attacked host would reply by sending
+ SYN-ACK packets and entering SYN-received state, thereby allocating
+ space for a TCB. At some point the SYN-queue would fill up, (i.e.,
+ the number of connections waiting to be established would rise to a
+ limit) and the host under attack would have to start turning down new
+ connection establishment requests.
+
+ TCP implementations with SYN-cookies algorithm [SYN-COOK] reduce the
+ risk of such blind denial of service attacks. TCP implementations
+ can switch to using this algorithm in times when their SYN-queues are
+ filled up while still fully conforming to the TCP specification
+ [RFC793]. However, use of options such as a window scale [RFC1323],
+ is not possible, then. With the SYN-cookie mechanism, a TCB is only
+ created when the client sends back a valid ACK packet to the server,
+ and the 3-way handshake has thus been successfully completed.
+
+ Blind connection forgery is another potential threat to TCP. By
+ guessing valid sequence numbers, an attacker would be able to forge a
+ connection. However, with a secure hashsum algorithm, for some of
+ the current SYN-cookie implementations the likelihood of achieving
+ this attack is on the order of magnitude of 1 in 2^24, i.e., the
+ attacker would have to send 2^24 packets before obtaining one forged
+ connection when SYN-cookies are used.
+
+5.2 Security issues with SCTP
+
+ SCTP has been designed with the experiences made with TCP in mind.
+ To make it hard for blind attackers (i.e., attackers that are not
+ man-in-the-middle) to inject forged SCTP datagrams into existing
+ associations, each side of an SCTP association uses a 32 bit value
+ called "Verification Tag" to ensure that a datagram really belongs to
+ the existing association. So in addition to a combination of source
+ and destination transport addresses that belong to an established
+ association, a valid SCTP datagram must also have the correct tag to
+ be accepted by the recipient.
+
+ Unlike in TCP, usage of cookie in association establishment is made
+ mandatory in SCTP. For the server, a new association is fully
+ established after three messages (containing INIT, INIT-ACK, COOKIE-
+ ECHO chunks) have been exchanged. The cookie is a variable length
+ parameter that contains all relevant data to initialize the TCB on
+ the server side, plus a HMAC used to secure it. This HMAC (MD5 as
+ per [RFC1321] or SHA-1 [SHA1]) is computed over the cookie and a
+ secret, server-owned key.
+
+
+
+
+
+Coene Informational [Page 7]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ As specifically prescribed for SCTP implementations [RFC2960],
+ additional resources for new associations may only be reserved in
+ case a valid COOKIE-ECHO chunk is received by a client, and the
+ computed HMAC for this new cookie matches that contained in the
+ cookie.
+
+ With SCTP the chances of an attacker being able to blindly forge a
+ connection are even lower than in the case of TCP using SYN-cookies,
+ since the attacker would have to guess a correct value for the HMAC
+ contained in the cookie, i.e., lower than 1 in 2^128 which for all
+ practical purposes is negligible.
+
+ It should be noted that SCTP only tries to increase the availability
+ of a network. SCTP does not contain any protocol mechanisms that are
+ directly related to user message authentication, integrity and
+ confidentiality functions. For such features, it depends on the
+ IPsec protocols and architecture and/or on security features of the
+ application protocols.
+
+ Transport Layer security(TLS)[RFC2246] using SCTP must always use
+ in-order streams.
+
+ Currently the IPSEC working group is investigating the support of
+ multi-homing by IPSEC protocols. At the present time to use IPSEC,
+ one must use 2 * N * M security associations if one endpoint uses N
+ addresses and the other M addresses.
+
+5.3 Security Issues with both TCP and SCTP
+
+ It is important to note that neither TCP nor SCTP protect itself from
+ man-in-the-middle attacks where an established session might be
+ hijacked (assuming the attacker can see the traffic from and inject
+ its own packets to either endpoints).
+
+ Also, to prevent blind connection/session setup forgery, both TCP
+ implementations supporting SYN-cookies and SCTP implementations rely
+ on a server-known, secret key to protect the HMAC data. It must be
+ ensured that this key is created subject to the recommendations
+ mentioned in [RFC1750].
+
+ Although SCTP has been designed carefully as to avoid some of the
+ problems that have appeared with TCP, it has as of yet not been
+ widely deployed. It is therefore possible that new security issues
+ will be identified that will have to be addressed in further
+ revisions of [RFC2960].
+
+
+
+
+
+
+Coene Informational [Page 8]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+6 References and related work
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L. and V. Paxson, "Stream Control Transmission
+ Protocol", RFC 2960, October 2000.
+
+ [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the
+ Internet Protocol", RFC 2401, November 1998.
+
+ [RFC2663] Srisuresh, P. and M. Holdrege, "IP Network Address
+ Translator (NAT) Terminology and Considerations", RFC
+ 2663, August 1999.
+
+ [RFC2694] Srisuresh, P., Tsirtsis, G., Akkiraju, P. and A.
+ Heffernan, "DNS extensions to Network Address Translators
+ (DNS_ALG)", RFC 2694, September 1999.
+
+ [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+ August 1980.
+
+ [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC
+ 793, September 1981.
+
+ [RFC2719] Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene,
+ L., Lin, H., Juhasz, I., Holdrege, M. and C. Sharp,
+ "Architectural Framework for Signaling Transport", RFC
+ 2719, October 1999.
+
+ [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+ April 1992.
+
+ [RFC1323] Jacobson, V., Braden, R. and D. Borman, "TCP Extensions
+ for High Performance", RFC 1323, May 1992.
+
+ [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
+ Recommendations for Security", RFC 1750, December 1994.
+
+ [SHA1] NIST FIPS PUB 180-1, "Secure Hash Standard," National
+ Institute of Standards and Technology, U.S. Department of
+ Commerce, April 1995.
+
+ [SYNCOOK] Dan J. Bernstein, SYN cookies, 1997, see also
+ <http://cr.yp.to/syncookies.html>
+
+ [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+ RFC 2246, January 1999.
+
+
+
+
+Coene Informational [Page 9]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+ [RFC1889] Schulzrinne, H., Casner, S., Frederick, R. and V.
+ Jacobson, "RTP: A Transport Protocol for Real-Time
+ Applications", RFC 1889, January 1996.
+
+7 Acknowledgments
+
+ This document was initially developed by a design team consisting of
+ Lode Coene, John Loughney, Michel Tuexen, Randall R. Stewart,
+ Qiaobing Xie, Matt Holdrege, Maria-Carmen Belinchon, Andreas
+ Jungmaier, Gery Verwimp and Lyndon Ong.
+
+ The authors wish to thank Renee Revis, I. Rytina, H.J. Schwarzbauer,
+ J.P. Martin-Flatin, T. Taylor, G. Sidebottom, K. Morneault, T.
+ George, M. Stillman, N. Makinae, S. Bradner, A. Mankin, G. Camarillo,
+ H. Schulzrinne, R. Kantola, J. Rosenberg, R.J. Atkinson, and many
+ others for their invaluable comments.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene Informational [Page 10]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+Appendix A: Major functions provided by SCTP
+
+ - Reliable Data Transfer
+
+ - Multiple streams to help avoid head-of-line blocking
+
+ - Ordered and unordered data delivery on a per-stream basis
+
+ - Bundling and fragmentation of user data
+
+ - TCP friendly Congestion and flow control
+
+ - Support continuous monitoring of reachability
+
+ - Graceful termination of association
+
+ - Support of multi-homing for added reliability
+
+ - Some protection against blind denial-of-service attacks
+
+ - Some protection against blind masquerade attacks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene Informational [Page 11]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+8 Editor's Address
+
+ Lode Coene
+ Siemens Atea
+ Atealaan 34
+ B-2200 Herentals
+ Belgium
+
+ Phone: +32-14-252081
+ EMail: lode.coene@siemens.atea.be
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene Informational [Page 12]
+
+RFC 3257 SCTP Applicability Statement April 2002
+
+
+9. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Coene Informational [Page 13]
+
diff --git a/doc/rfc3286.txt b/doc/rfc3286.txt
new file mode 100644
index 0000000..aa446a4
--- /dev/null
+++ b/doc/rfc3286.txt
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group L. Ong
+Request for Comments: 3286 Ciena Corporation
+Category: Informational J. Yoakum
+ Nortel Networks
+ May 2002
+
+
+ An Introduction to the Stream Control Transmission Protocol (SCTP)
+
+Status of this Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+Abstract
+
+ This document provides a high level introduction to the capabilities
+ supported by the Stream Control Transmission Protocol (SCTP). It is
+ intended as a guide for potential users of SCTP as a general purpose
+ transport protocol.
+
+1. Introduction
+
+ The Stream Control Transmission Protocol (SCTP) is a new IP transport
+ protocol, existing at an equivalent level with UDP (User Datagram
+ Protocol) and TCP (Transmission Control Protocol), which provide
+ transport layer functions to many Internet applications. SCTP has
+ been approved by the IETF as a Proposed Standard [1]. The error
+ check algorithm has since been modified [2]. Future changes and
+ updates will be reflected in the IETF RFC index.
+
+ Like TCP, SCTP provides a reliable transport service, ensuring that
+ data is transported across the network without error and in sequence.
+ Like TCP, SCTP is a session-oriented mechanism, meaning that a
+ relationship is created between the endpoints of an SCTP association
+ prior to data being transmitted, and this relationship is maintained
+ until all data transmission has been successfully completed.
+
+ Unlike TCP, SCTP provides a number of functions that are critical for
+ telephony signaling transport, and at the same time can potentially
+ benefit other applications needing transport with additional
+ performance and reliability. The original framework for the SCTP
+ definition is described in [3].
+
+
+
+Ong & Yoakum Informational [Page 1]
+
+RFC 3286 SCTP Overview May 2002
+
+
+2. Basic SCTP Features
+
+ SCTP is a unicast protocol, and supports data exchange between
+ exactly 2 endpoints, although these may be represented by multiple IP
+ addresses.
+
+ SCTP provides reliable transmission, detecting when data is
+ discarded, reordered, duplicated or corrupted, and retransmitting
+ damaged data as necessary. SCTP transmission is full duplex.
+
+ SCTP is message oriented and supports framing of individual message
+ boundaries. In comparison, TCP is byte oriented and does not
+ preserve any implicit structure within a transmitted byte stream
+ without enhancement.
+
+ SCTP is rate adaptive similar to TCP, and will scale back data
+ transfer to the prevailing load conditions in the network. It is
+ designed to behave cooperatively with TCP sessions attempting to use
+ the same bandwidth.
+
+3. SCTP Multi-Streaming Feature
+
+ The name Stream Control Transmission Protocol is derived from the
+ multi-streaming function provided by SCTP. This feature allows data
+ to be partitioned into multiple streams that have the property of
+ independently sequenced delivery, so that message loss in any one
+ stream will only initially affect delivery within that stream, and
+ not delivery in other streams.
+
+ In contrast, TCP assumes a single stream of data and ensures that
+ delivery of that stream takes place with byte sequence preservation.
+ While this is desirable for delivery of a file or record, it causes
+ additional delay when message loss or sequence error occurs within
+ the network. When this happens, TCP must delay delivery of data
+ until the correct sequencing is restored, either by receipt of an
+ out-of-sequence message, or by retransmission of a lost message.
+
+ For a number of applications, the characteristic of strict sequence
+ preservation is not truly necessary. In telephony signaling, it is
+ only necessary to maintain sequencing of messages that affect the
+ same resource (e.g., the same call, or the same channel). Other
+ messages are only loosely correlated and can be delivered without
+ having to maintain overall sequence integrity.
+
+ Another example of possible use of multi-streaming is the delivery of
+ multimedia documents, such as a web page, when done over a single
+ session. Since multimedia documents consist of objects of different
+ sizes and types, multi-streaming allows transport of these components
+
+
+
+Ong & Yoakum Informational [Page 2]
+
+RFC 3286 SCTP Overview May 2002
+
+
+ to be partially ordered rather than strictly ordered, and may result
+ in improved user perception of transport.
+
+ At the same time, transport is done within a single SCTP association,
+ so that all streams are subjected to a common flow and congestion
+ control mechanism, reducing the overhead required at the transport
+ level.
+
+ SCTP accomplishes multi-streaming by creating independence between
+ data transmission and data delivery. In particular, each payload
+ DATA "chunk" in the protocol uses two sets of sequence numbers, a
+ Transmission Sequence Number that governs the transmission of
+ messages and the detection of message loss, and the Stream ID/Stream
+ Sequence Number pair, which is used to determine the sequence of
+ delivery of received data.
+
+ This independence of mechanisms allows the receiver to determine
+ immediately when a gap in the transmission sequence occurs (e.g., due
+ to message loss), and also whether or not messages received following
+ the gap are within an affected stream. If a message is received
+ within the affected stream, there will be a corresponding gap in the
+ Stream Sequence Number, while messages from other streams will not
+ show a gap. The receiver can therefore continue to deliver messages
+ to the unaffected streams while buffering messages in the affected
+ stream until retransmission occurs.
+
+4. SCTP Multi-Homing Feature
+
+ Another core feature of SCTP is multi-homing, or the ability for a
+ single SCTP endpoint to support multiple IP addresses. The benefit
+ of multi-homing is potentially greater survivability of the session
+ in the presence of network failures. In a conventional single-homed
+ session, the failure of a local LAN access can isolate the end
+ system, while failures within the core network can cause temporary
+ unavailability of transport until the IP routing protocols can
+ reconverge around the point of failure. Using multi-homed SCTP,
+ redundant LANs can be used to reinforce the local access, while
+ various options are possible in the core network to reduce the
+ dependency of failures for different addresses. Use of addresses
+ with different prefixes can force routing to go through different
+ carriers, for example, route-pinning techniques or even redundant
+ core networks can also be used if there is control over the network
+ architecture and protocols.
+
+ In its current form, SCTP does not do load sharing, that is, multi-
+ homing is used for redundancy purposes only. A single address is
+ chosen as the "primary" address and is used as the destination for
+ all DATA chunks for normal transmission. Retransmitted DATA chunks
+
+
+
+Ong & Yoakum Informational [Page 3]
+
+RFC 3286 SCTP Overview May 2002
+
+
+ use the alternate address(es) to improve the probability of reaching
+ the remote endpoint, while continued failure to send to the primary
+ address ultimately results in the decision to transmit all DATA
+ chunks to the alternate until heartbeats can reestablish the
+ reachability of the primary.
+
+ To support multi-homing, SCTP endpoints exchange lists of addresses
+ during initiation of the association. Each endpoint must be able to
+ receive messages from any of the addresses associated with the remote
+ endpoint; in practice, certain operating systems may utilize
+ available source addresses in round robin fashion, in which case
+ receipt of messages from different source addresses will be the
+ normal case. A single port number is used across the entire address
+ list at an endpoint for a specific session.
+
+ In order to reduce the potential for security issues, it is required
+ that some response messages be sent specifically to the source
+ address in the message that caused the response. For example, when
+ the server receives an INIT chunk from a client to initiate an SCTP
+ association, the server always sends the response INIT ACK chunk to
+ the source address that was in the IP header of the INIT.
+
+5. Features of the SCTP Initiation Procedure
+
+ The SCTP Initiation Procedure relies on a 4-message sequence, where
+ DATA can be included on the 3rd and 4th messages of the sequence, as
+ these messages are sent when the association has already been
+ validated. A "cookie" mechanism has been incorporated into the
+ sequence to guard against some types of denial of service attacks.
+
+5.1 Cookie Mechanism
+
+ The "cookie" mechanism guards specifically against a blind attacker
+ generating INIT chunks to try to overload the resources of an SCTP
+ server by causing it to use up memory and resources handling new INIT
+ requests. Rather than allocating memory for a Transmission Control
+ Block (TCB), the server instead creates a Cookie parameter with the
+ TCB information, together with a valid lifetime and a signature for
+ authentication, and sends this back in the INIT ACK. Since the INIT
+ ACK always goes back to the source address of the INIT, the blind
+ attacker will not get the Cookie. A valid SCTP client will get the
+ Cookie and return it in the COOKIE ECHO chunk, where the SCTP server
+ can validate the Cookie and use it to rebuild the TCB. Since the
+ server creates the Cookie, only it needs to know the format and
+ secret key, this is not exchanged with the client.
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 4]
+
+RFC 3286 SCTP Overview May 2002
+
+
+ Otherwise, the SCTP Initiation Procedure follows many TCP
+ conventions, so that the endpoints exchange receiver windows, initial
+ sequence numbers, etc. In addition to this, the endpoints may
+ exchange address lists as discussed above, and also mutually confirm
+ the number of streams to be opened on each side.
+
+5.2 INIT Collision Resolution
+
+ Multi-homing adds to the potential that messages will be received out
+ of sequence or with different address pairs. This is a particular
+ concern during initiation of the association, where without
+ procedures for resolving the collision of messages, you may easily
+ end up with multiple parallel associations between the same
+ endpoints. To avoid this, SCTP incorporates a number of procedures
+ to resolve parallel initiation attempts into a single association.
+
+6. SCTP DATA Exchange Features
+
+ DATA chunk exchange in SCTP follows TCP's Selective ACK procedure.
+ Receipt of DATA chunks is acknowledged by sending SACK chunks, which
+ indicate not only the cumulative Transmission Sequence Number (TSN)
+ range received, but also any non-cumulative TSNs, implying gaps in
+ the received TSN sequence. Following TCP procedures, SACKs are sent
+ using the "delayed ack" method, normally one SACK per every other
+ received packet, but with an upper limit on the delay between SACKs
+ and an increase to once per received packet when there are gaps
+ detected.
+
+ Flow and Congestion Control follow TCP algorithms. The advertised
+ receive window indicates buffer occupancy at the receiver, while a
+ per-path congestion window is maintained to manage the packets in
+ flight. Slow start, Congestion avoidance, Fast recovery and Fast
+ retransmit are incorporated into the procedures as described in RFC
+ 2581, with the one change being that the endpoints must manage the
+ conversion between bytes sent and received and TSNs sent and
+ received, since TSN is per chunk rather than per byte.
+
+ The application can specify a lifetime for data to be transmitted, so
+ that if the lifetime has expired and the data has not yet been
+ transmitted, it can be discarded (e.g., time-sensitive signaling
+ messages). If the data has been transmitted, it must continue to be
+ delivered to avoid creating a hole in the TSN sequence.
+
+
+
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 5]
+
+RFC 3286 SCTP Overview May 2002
+
+
+7. SCTP Shutdown Features
+
+ SCTP Shutdown uses a 3-message procedure to allow graceful shutdown,
+ where each endpoint has confirmation of the DATA chunks received by
+ the remote endpoint prior to completion of the shutdown. An Abort
+ procedure is also provided for error cases when an immediate shutdown
+ must take place.
+
+ Note that SCTP does not support the function of a "half-open"
+ connection as can occur in TCP, when one side indicates that it has
+ no more data to send, but the other side can continue to send data
+ indefinitely. SCTP assumes that once the shutdown procedure begins,
+ both sides will stop sending new data across the association, and
+ only need to clear up acknowledgements of previously sent data.
+
+8. SCTP Message Format
+
+ The SCTP Message includes a common header plus one or more chunks,
+ which can be control or data. The common header has source and
+ destination port numbers to allow multiplexing of different SCTP
+ associations at the same address, a 32-bit verification tag that
+ guards against insertion of an out-of-date or false message into the
+ SCTP association, and a 32-bit checksum (this has been modified to
+ use the CRC-32c polynomial [2]) for error detection.
+
+ Each chunk includes chunk type, flag field, length and value.
+ Control chunks incorporate different flags and parameters depending
+ on the chunk type. DATA chunks in particular incorporate flags for
+ control of segmentation and reassembly, and parameters for the TSN,
+ Stream ID and Stream Sequence Number, and a Payload Protocol
+ Identifier.
+
+ The Payload Protocol ID has been included for future flexibility. It
+ is envisioned that the functions of protocol identification and port
+ number multiplexing will not be as closely linked in the future as
+ they are in current usage. Payload Protocol ID will allow the
+ protocol being carried by SCTP to be identified independent of the
+ port numbers being used.
+
+ The SCTP message format naturally allows support of bundling of
+ multiple DATA and control chunks in a single message, to improve
+ transport efficiency. Use of bundling is controllable by the
+ application, so that bundling of initial transmission can be
+ prohibited. Bundling will naturally occur on retransmission of DATA
+ chunks, to further reduce any chance of congestion.
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 6]
+
+RFC 3286 SCTP Overview May 2002
+
+
+9. Error Handling
+
+9.1 Retransmission
+
+ Retransmission of DATA chunks occurs from either (a) timeout of the
+ retransmission timer; or (b) receipt of SACKs indicating the DATA
+ chunk has not been received. To reduce the potential for congestion,
+ the rate of retransmission of DATA chunks is limited. The
+ retransmission timeout (RTO) is adjusted based on estimates of the
+ round trip delay and backs off exponentially as message loss
+ increases.
+
+ In an active association with fairly constant DATA transmission,
+ SACKs are more likely to cause retransmission than the timeout. To
+ reduce the chance of an unnecessary retransmission, a 4 SACK rule is
+ used, so that retransmission only occurs on receipt of the 4th SACK
+ that indicates that the chunk is missing. This is intended to avoid
+ retransmits due to normal occurrences such as packets received out of
+ sequence.
+
+9.2 Path Failure
+
+ A count is maintained of the number of retransmissions to a
+ particular destination address without successful acknowledgement.
+ When this count exceeds a configured maximum, the address is declared
+ inactive, notification is given to the application, and the SCTP
+ begins to use an alternate address for the sending of DATA chunks.
+
+ Also, Heartbeat chunks are sent periodically to all idle destinations
+ (i.e., alternate addresses), and a counter is maintained on the
+ number of Heartbeats sent to an inactive destination without receipt
+ of a corresponding Heartbeat Ack. When this counter exceeds a
+ configured maximum, that destination address is also declared
+ inactive.
+
+ Heartbeats continue to be sent to inactive destination addresses
+ until an Ack is received, at which point the address can be made
+ active again. The rate of sending Heartbeats is tied to the RTO
+ estimation plus an additional delay parameter that allows Heartbeat
+ traffic to be tailored according to the needs of the user
+ application.
+
+9.3 Endpoint Failure
+
+ A count is maintained across all destination addresses on the number
+ of retransmits or Heartbeats sent to the remote endpoint without a
+ successful Ack. When this exceeds a configured maximum, the endpoint
+ is declared unreachable, and the SCTP association is closed.
+
+
+
+Ong & Yoakum Informational [Page 7]
+
+RFC 3286 SCTP Overview May 2002
+
+
+10. API
+
+ The specification includes a model of the primitives exchanged
+ between the application and the SCTP layer, intended as informational
+ material rather than a formal API statement. A socket-based API is
+ being defined to simplify migration of TCP or UDP applications to the
+ use of SCTP.
+
+11. Security Considerations
+
+ In addition to the verification tag and cookie mechanisms, SCTP
+ specifies the use of IPSec if strong security and integrity
+ protection is required. The SCTP specification does not itself
+ define any new security protocols or procedures.
+
+ Extensions to IPSec are under discussion to reduce the overhead
+ required to support multi-homing. Also, work is in progress on the
+ use of Transport Layer Security (TLS) over SCTP [4].
+
+12. Extensions
+
+ The SCTP format allows new chunk types, flags and parameter fields to
+ be defined as extensions to the protocol. Any extensions must be
+ based on standard agreements within the IETF, as no vendor-specific
+ extensions are supported in the protocol.
+
+ Chunk Type values are organized into four ranges to allow extensions
+ to be made with a pre-defined procedure for responding if a new Chunk
+ Type is not recognized at the remote endpoint. Responses include:
+ whole packet discard; packet discard with reporting; ignoring the
+ chunk; ignoring with reporting. Similar pre-defined responses are
+ specified for unrecognized Parameter Type values.
+
+ Chunk Parameter Type values are in principle independent ranges for
+ each Chunk Type. In practice, the values defined in the SCTP
+ specification have been coordinated so that a particular parameter
+ type will have the same Chunk Parameter Type value across all Chunk
+ Types. Further experience will determine if this alignment needs to
+ be maintained or formalized.
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 8]
+
+RFC 3286 SCTP Overview May 2002
+
+
+13. Informative References
+
+ [1] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H.,
+ Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+ [2] Stewart, Sharp, et. al., "SCTP Checksum Change", Work in
+ Progress.
+
+ [3] Ong, L., Rytina, I., Garcia, M., Schwarzbauer, H., Coene, L.,
+ Lin, H., Juhasz, I., Holdrege, M. and C. Sharp, "Framework
+ Architecture for Signaling Transport", RFC 2719, October 1999.
+
+ [4] Jungmeier, Rescorla and Tuexen, "TLS Over SCTP", Work in
+ Progress.
+
+14. Authors' Addresses
+
+ Lyndon Ong
+ Ciena Corporation
+ 10480 Ridgeview Drive
+ Cupertino, CA 95014
+
+ EMail: lyong@ciena.com
+
+
+ John Yoakum
+ Emerging Opportunities
+ Nortel Networks
+
+ EMail: yoakum@nortelnetworks.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 9]
+
+RFC 3286 SCTP Overview May 2002
+
+
+15. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ong & Yoakum Informational [Page 10]
+
diff --git a/doc/rfc3309.txt b/doc/rfc3309.txt
new file mode 100644
index 0000000..494fee1
--- /dev/null
+++ b/doc/rfc3309.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group J. Stone
+Request for Comments: 3309 Stanford
+Updates: 2960 R. Stewart
+Category: Standards Cisco Systems
+ D. Otis
+ SANlight
+ September 2002
+
+
+ Stream Control Transmission Protocol (SCTP) Checksum Change
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+Abstract
+
+ Stream Control Transmission Protocol (SCTP) currently uses an Adler-
+ 32 checksum. For small packets Adler-32 provides weak detection of
+ errors. This document changes that checksum and updates SCTP to use
+ a 32 bit CRC checksum.
+
+Table of Contents
+
+ 1 Introduction ................................................... 2
+ 2 Checksum Procedures ............................................ 3
+ 3 Security Considerations......................................... 6
+ 4 IANA Considerations............................................. 6
+ 5 Acknowledgments ................................................ 6
+ 6 References ..................................................... 7
+ Appendix ......................................................... 9
+ Authors' Addresses ............................................... 16
+ Full Copyright Statement ......................................... 17
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 1]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+1 Introduction
+
+ A fundamental weakness has been detected in SCTP's current Adler-32
+ checksum algorithm [STONE]. This document updates and replaces the
+ Adler-32 checksum definition in [RFC 2960]. Note that there is no
+ graceful transition mechanism for migrating to the new checksum.
+ Implementations are expected to immediately switch to the new
+ algorithm; use of the old algorithm is deprecated.
+
+ One requirement of an effective checksum is that it evenly and
+ smoothly spreads its input packets over the available check bits.
+
+ From an email from Jonathan Stone, who analyzed the Adler-32 as part
+ of his doctoral thesis:
+
+ "Briefly, the problem is that, for very short packets, Adler32 is
+ guaranteed to give poor coverage of the available bits. Don't take
+ my word for it, ask Mark Adler. :-)
+
+ Adler-32 uses two 16-bit counters, s1 and s2. s1 is the sum of the
+ input, taken as 8-bit bytes. s2 is a running sum of each value of
+ s1. Both s1 and s2 are computed mod-65521 (the largest prime less
+ than 2^16). Consider a packet of 128 bytes. The *most* that each
+ byte can be is 255. There are only 128 bytes of input, so the
+ greatest value which the s1 accumulator can have is 255 * 128 =
+ 32640. So, for 128-byte packets, s1 never wraps. That is critical.
+ Why?
+
+ The key is to consider the distribution of the s1 values, over some
+ distribution of the values of the individual input bytes in each
+ packet. Because s1 never wraps, s1 is simply the sum of the
+ individual input bytes. (Even Doug's trick of adding 0x5555 doesn't
+ help here, and an even larger value doesn't really help: we can get
+ at most one mod-65521 reduction.)
+
+ Given the further assumption that the input bytes are drawn
+ independently from some distribution (they probably aren't: for file
+ system data, it's even worse than that!), the Central Limit Theorem
+ tells us that that s1 will tend to have a normal distribution.
+ That's bad: it tells us that the value of s1 will have hot-spots at
+ around 128 times the mean of the input distribution: around 16k,
+ assuming a uniform distribution. That's bad. We want the
+ accumulator to wrap as many times as possible, so that the resulting
+ sum has as close to a uniform distribution as possible. (I call this
+ "fairness".)
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 2]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ So, for short packets, the Adler-32 s1 sum is guaranteed to be
+ unfair. Why is that bad? It's bad because the space of valid
+ packets -- input data, plus checksum values -- is also small. If all
+ packets have checksum values very close to 32640, then the likelihood
+ of even a 'small' error leaving a damaged packet with a valid
+ checksum is higher than if all checksum values are equally likely."
+
+ Due to this inherent weakness, exacerbated by the fact that SCTP will
+ first be used as a signaling transport protocol where signaling
+ messages are usually less than 128 bytes, a new checksum algorithm is
+ specified by this document, replacing the current Adler-32 algorithm
+ with CRC-32c.
+
+1.1 Conventions
+
+ The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT,
+ SHOULD,SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL,
+ when they appear in this document, are to be interpreted as described
+ in [RFC2119].
+
+ Bit number order is defined in [RFC1700].
+
+2 Checksum Procedures
+
+ The procedures described in section 2.1 of this document MUST be
+ followed, replacing the current checksum defined in [RFC2960].
+
+ Furthermore any references within [RFC2960] to Adler-32 MUST be
+ treated as a reference to CRC-32c. Section 2.1 of this document
+ describes the new calculation and verification procedures that MUST
+ be followed.
+
+2.1 Checksum Calculation
+
+ When sending an SCTP packet, the endpoint MUST strengthen the data
+ integrity of the transmission by including the CRC-32c checksum value
+ calculated on the packet, as described below.
+
+ After the packet is constructed (containing the SCTP common header
+ and one or more control or DATA chunks), the transmitter shall:
+
+ 1) Fill in the proper Verification Tag in the SCTP common header and
+ initialize the Checksum field to 0's.
+
+ 2) Calculate the CRC-32c of the whole packet, including the SCTP
+ common header and all the chunks.
+
+
+
+
+
+Stone, et. al. Standards Track [Page 3]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ 3) Put the resulting value into the Checksum field in the common
+ header, and leave the rest of the bits unchanged.
+
+ When an SCTP packet is received, the receiver MUST first check the
+ CRC-32c checksum:
+
+ 1) Store the received CRC-32c value,
+
+ 2) Replace the 32 bits of the Checksum field in the received SCTP
+ packet with all '0's and calculate a CRC-32c value of the whole
+ received packet. And,
+
+ 3) Verify that the calculated CRC-32c value is the same as the
+ received CRC-32c value. If not, the receiver MUST treat the
+ packet as an invalid SCTP packet.
+
+ The default procedure for handling invalid SCTP packets is to
+ silently discard them.
+
+ Any hardware implementation SHOULD be done in a way that is
+ verifiable by the software.
+
+ We define a 'reflected value' as one that is the opposite of the
+ normal bit order of the machine. The 32 bit CRC is calculated as
+ described for CRC-32c and uses the polynomial code 0x11EDC6F41
+ (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+ +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0. The
+ CRC is computed using a procedure similar to ETHERNET CRC [ITU32],
+ modified to reflect transport level usage.
+
+ CRC computation uses polynomial division. A message bit-string M is
+ transformed to a polynomial, M(X), and the CRC is calculated from
+ M(X) using polynomial arithmetic [Peterson 72].
+
+ When CRCs are used at the link layer, the polynomial is derived from
+ on-the-wire bit ordering: the first bit 'on the wire' is the high-
+ order coefficient. Since SCTP is a transport-level protocol, it
+ cannot know the actual serial-media bit ordering. Moreover,
+ different links in the path between SCTP endpoints may use different
+ link-level bit orders.
+
+ A convention must therefore be established for mapping SCTP transport
+ messages to polynomials for purposes of CRC computation. The bit-
+ ordering for mapping SCTP messages to polynomials is that bytes are
+ taken most-significant first; but within each byte, bits are taken
+ least-significant first. The first byte of the message provides the
+ eight highest coefficients. Within each byte, the least-significant
+ SCTP bit gives the most significant polynomial coefficient within
+
+
+
+Stone, et. al. Standards Track [Page 4]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ that byte, and the most-significant SCTP bit is the least significant
+ polynomial coefficient in that byte. (This bit ordering is sometimes
+ called 'mirrored' or 'reflected' [Williams93].) CRC polynomials are
+ to be transformed back into SCTP transport-level byte values, using a
+ consistent mapping.
+
+ The SCTP transport-level CRC value should be calculated as follows:
+
+ - CRC input data are assigned to a byte stream, numbered from 0
+ to N-1.
+
+ - the transport-level byte-stream is mapped to a polynomial
+ value. An N-byte PDU with j bytes numbered 0 to N-1, is
+ considered as coefficients of a polynomial M(x) of order 8N-1,
+ with bit 0 of byte j being coefficient x^(8(N-j)-8), bit 7 of
+ byte j being coefficient x^(8(N-j)-1).
+
+ - the CRC remainder register is initialized with all 1s and the
+ CRC is computed with an algorithm that simultaneously
+ multiplies by x^32 and divides by the CRC polynomial.
+
+ - the polynomial is multiplied by x^32 and divided by G(x), the
+ generator polynomial, producing a remainder R(x) of degree less
+ than or equal to 31.
+
+ - the coefficients of R(x) are considered a 32 bit sequence.
+
+ - the bit sequence is complemented. The result is the CRC
+ polynomial.
+
+ - The CRC polynomial is mapped back into SCTP transport-level
+ bytes. Coefficient of x^31 gives the value of bit 7 of SCTP
+ byte 0, the coefficient of x^24 gives the value of bit 0 of
+ byte 0. The coefficient of x^7 gives bit 7 of byte 3 and the
+ coefficient of x^0 gives bit 0 of byte 3. The resulting four-
+ byte transport-level sequence is the 32-bit SCTP checksum
+ value.
+
+ IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+ literature on CRCs often follow an alternative formulation, in which
+ the register used to hold the remainder of the long-division
+ algorithm is initialized to zero rather than all-1s, and instead the
+ first 32 bits of the message are complemented. The long-division
+ algorithm used in our formulation is specified, such that the the
+ initial multiplication by 2^32 and the long-division are combined
+ into one simultaneous operation. For such algorithms, and for
+ messages longer than 64 bits, the two specifications are precisely
+ equivalent. That equivalence is the intent of this document.
+
+
+
+Stone, et. al. Standards Track [Page 5]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ Implementors of SCTP are warned that both specifications are to be
+ found in the literature, sometimes with no restriction on the long-
+ division algorithm. The choice of formulation in this document is to
+ permit non-SCTP usage, where the same CRC algorithm may be used to
+ protect messages shorter than 64 bits.
+
+ If SCTP could follow link level CRC use, the CRC would be computed
+ over the link-level bit-stream. The first bit on the link mapping to
+ the highest-order coefficient, and so on, down to the last link-level
+ bit as the lowest-order coefficient. The CRC value would be
+ transmitted immediately after the input message as a link-level
+ 'trailer'. The resulting link-level bit-stream would be (M(X)x) *
+ x^32) + (M(X)*x^32))/ G(x), which is divisible by G(X). There would
+ thus be a constant CRC remainder for 'good' packets. However, given
+ that implementations of RFC 2960 have already proliferated, the IETF
+ discussions considered that the benefit of a 'trailer' CRC did not
+ outweigh the cost of making a very large change in the protocol
+ processing. Further, packets accepted by the SCTP 'header' CRC are
+ in one-to-one correspondence with packets accepted by a modified
+ procedure using a 'trailer' CRC value, and where the SCTP common
+ checksum header is set to zero on transmission and is received as
+ zero.
+
+ There may be a computational advantage in validating the Association
+ against the Verification Tag, prior to performing a checksum, as
+ invalid tags will result in the same action as a bad checksum in most
+ cases. The exceptions for this technique would be INIT and some
+ SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE-ECHO. These
+ special case exchanges must represent small packets and will minimize
+ the effect of the checksum calculation.
+
+3 Security Considerations
+
+ In general, the security considerations of RFC 2960 apply to the
+ protocol with the new checksum as well.
+
+4 IANA Considerations
+
+ There are no IANA considerations required in this document.
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 6]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+5 Acknowledgments
+
+ The authors would like to thank the following people that have
+ provided comments and input on the checksum issue:
+
+ Mark Adler, Ran Atkinson, Stephen Bailey, David Black, Scott Bradner,
+ Mikael Degermark, Laurent Glaude, Klaus Gradischnig, Alf Heidermark,
+ Jacob Heitz, Gareth Kiely, David Lehmann, Allision Mankin, Lyndon
+ Ong, Craig Partridge, Vern Paxson, Kacheong Poon, Michael Ramalho,
+ David Reed, Ian Rytina, Hanns Juergen Schwarzbauer, Chip Sharp, Bill
+ Sommerfeld, Michael Tuexen, Jim Williams, Jim Wendt, Michael Welzl,
+ Jonathan Wood, Lloyd Wood, Qiaobing Xie, La Monte Yarroll.
+
+ Special thanks to Dafna Scheinwald, Julian Satran, Pat Thaler, Matt
+ Wakeley, and Vince Cavanna, for selection criteria of polynomials and
+ examination of CRC polynomials, particularly CRC-32c [Castagnoli93].
+
+ Special thanks to Mr. Ross Williams and his document [Williams93].
+ This non-formal perspective on software aspects of CRCs furthered
+ understanding of authors previously unfamiliar with CRC computation.
+ More formal treatments of [Blahut 94] or [Peterson 72], was also
+ essential.
+
+6 References
+
+ [Castagnoli93] G. Castagnoli, S. Braeuer and M. Herrman,
+ "Optimization of Cyclic Redundancy-Check Codes with
+ 24 and 32 Parity Bits", IEEE Transactions on
+ Communications, Vol. 41, No. 6, June 1993
+
+ [McKee75] H. McKee, "Improved {CRC} techniques detects
+ erroneous leading and trailing 0's in transmitted
+ data blocks", Computer Design Volume 14 Number 10
+ Pages 102-4,106, October 1975
+
+ [RFC1700] Reynolds, J. and J. Postel, "ASSIGNED NUMBERS", RFC
+ 1700, October 1994.
+
+ [RFC2026] Bradner, S., "The Internet Standards Process --
+ Revision 3", BCP 9, RFC 2026, October 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L. and V. Paxson, "Stream Control Transmission
+ Protocol," RFC 2960, October 2000.
+
+
+
+Stone, et. al. Standards Track [Page 7]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ [ITU32] ITU-T Recommendation V.42, "Error-correcting
+ procedures for DCEs using asynchronous-to-synchronous
+ conversion", section 8.1.1.6.2, October 1996.
+
+7.1 Informative References
+
+ [STONE] Stone, J., "Checksums in the Internet", Doctoral
+ dissertation - August 2001.
+
+ [Williams93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR
+ DETECTION ALGORITHMS" - Internet publication, August
+ 1993,
+ http://www.geocities.com/SiliconValley/Pines/
+ 8659/crc.htm.
+
+ [Blahut 1994] R.E. Blahut, Theory and Practice of Error Control
+ Codes, Addison-Wesley, 1994.
+
+ [Easics 2001] http://www.easics.be/webtools/crctool. Online tools
+ for synthesis of CRC Verilog and VHDL.
+
+ [Feldmeier 95] David C. Feldmeier, Fast software implementation of
+ error detection codes, IEEE Transactions on
+ Networking, vol 3 no 6, pp 640-651, December, 1995.
+
+ [Glaise 1997] R. J. Glaise, A two-step computation of cyclic
+ redundancy code CRC-32 for ATM networks, IBM Journal
+ of Research and Development} vol 41 no 6, 1997.
+ http://www.research.ibm.com/journal/rd/416/
+ glaise.html.
+
+ [Prange 1957] E. Prange, Cyclic Error-Correcting codes in two
+ symbols, Technical report AFCRC-TN-57-103, Air Force
+ Cambridge Research Center, Cambridge, Mass. 1957.
+
+ [Peterson 1972] W. W. Peterson and E.J Weldon, Error Correcting
+ Codes, 2nd. edition, MIT Press, Cambridge,
+ Massachusetts.
+
+ [Shie2001] Ming-Der Shieh et. al, A Systematic Approach for
+ Parallel CRC Computations. Journal of Information
+ Science and Engineering, Vol.17 No.3, pp.445-461
+
+ [Sprachman2001] Michael Sprachman, Automatic Generation of Parallel
+ CRC Circuits, IEEE Design & Test May-June 2001
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 8]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+Appendix
+
+ This appendix is for information only and is NOT part of the
+ standard.
+
+ The anticipated deployment of SCTP ranges over several orders of
+ magnitude of link speed: from cellular-power telephony devices at
+ tens of kilobits, to local links at tens of gigabits. Implementors
+ of SCTP should consider their link speed and choose, from the wide
+ range of CRC implementations, one which matches their own design
+ point for size, cost, and throughput. Many techniques for computing
+ CRCs are known. This Appendix surveys just a few, to give a feel for
+ the range of techniques available.
+
+ CRCs are derived from early work by Prange in the 1950s [Prange 57].
+ The theory underlying CRCs and choice of generator polynomial can be
+ introduced by either the theory of Galois fields [Blahut 94] or as
+ ideals of an algebra over cyclic codes [cite Peterson 72].
+
+ One of the simplest techniques is direct bit-serial hardware
+ implementations, using the generator polynomial as the taps of a
+ linear feedback shift register (LSFR). LSFR computation follows
+ directly from the mathematics, and is generally attributed to Prange.
+ Tools exist which, a CRC generator polynomial, will produce
+ synthesizable Verilog code for CRC hardware [Easics 2001].
+
+ Since LSFRs do not scale well in speed, a variety of other techniques
+ have been explored. One technique exploits the fact that the divisor
+ of the polynomial long-division, G, is known in advance. It is thus
+ possible to pre-compute lookup tables giving the polynomial remainder
+ of multiple input bits --- typically 2, 4, or 8 bits of input at a
+ time. This technique can be used either in software or in hardware.
+ Software to compute lookup tables yielding 2, 4, or 8 bits of result
+ is freely available. [Williams93]
+
+ For multi-gigabit links, the above techniques may still not be fast
+ enough. One technique for computing CRCS at OC-48 rates is 'two-
+ stage' CRC computation [Glaise 1997]. Here, some multiple of G(x),
+ G(x)H(x), is chosen so as to minimize the number of nonzero
+ coefficients, or weight, of the product G(x)H(x). The low weight of
+ the product polynomial makes it susceptible to efficient hardware
+ divide-by-constant implementations. This first stage gives M(x)/
+ (G(x)H(x)), as its result. The second stage then divides the result
+ of the first stage by H(x), yielding (M(x)/(G(x)H(x)))/H(x). If H(x)
+ is also relatively prime to G(x), this gives M(x)/G(x). Further
+ developments on this approach can be found in [Shie2001] and
+ [Sprachman2001].
+
+
+
+
+Stone, et. al. Standards Track [Page 9]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ The literature also includes a variety of software CRC
+ implementations. One approach is to use a carefully-tuned assembly
+ code for direct polynomial division. [Feldmeier 95] reports that for
+ low-weight polynomials, tuned polynomial arithmetic gives higher
+ throughput than table-lookup algorithms. Even within table-lookup
+ algorithms, the size of the table can be tuned, either for total
+ cache footprint, or (for space-restricted environments) to minimize
+ total size.
+
+ Implementors should keep in mind, the bit ordering described in
+ Section 2: the ordering of bits within bytes for computing CRCs in
+ SCTP is the least significant bit of each byte is the most-
+ significant polynomial coefficient(and vice-versa). This 'reflected'
+ SCTP CRC bit ordering matches on-the-wire bit order for Ethernet and
+ other serial media, but is the reverse of traditional Internet bit
+ ordering.
+
+ One technique to accommodate this bit-reversal can be explained as
+ follows: sketch out a hardware implementation, assuming the bits are
+ in CRC bit order; then perform a left-to-right inversion (mirror
+ image) on the entire algorithm. (We defer, for a moment, the issue
+ of byte order within words.) Then compute that "mirror image" in
+ software. The CRC from the "mirror image" algorithm will be the
+ bit-reversal of a correct hardware implementation. When the link-
+ level media sends each byte, the byte is sent in the reverse of the
+ host CPU bit-order. Serialization of each byte of the "reflected"
+ CRC value re-reverses the bit order, so in the end, each byte will be
+ transmitted on-the-wire in the specified bit order.
+
+ The following non-normative sample code is taken from an open-source
+ CRC generator [Williams93], using the "mirroring" technique and
+ yielding a lookup table for SCTP CRC32-c with 256 entries, each 32
+ bits wide. While neither especially slow nor especially fast, as
+ software table-lookup CRCs go, it has the advantage of working on
+ both big-endian and little-endian CPUs, using the same (host-order)
+ lookup tables, and using only the pre-defined ntohl() and htonl()
+ operations. The code is somewhat modified from [Williams93], to
+ ensure portability between big-endian and little-endian
+ architectures. (Note that if the byte endian-ness of the target
+ architecture is known to be little-endian the final bit-reversal and
+ byte-reversal steps can be folded into a single operation.)
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 10]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+/*************************************************************/
+/* Note Definition for Ross Williams table generator would */
+/* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE */
+/* For Mr. Williams direct calculation code use the settings */
+/* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF, */
+/* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000 */
+/*************************************************************/
+
+/* Example of the crc table file */
+#ifndef __crc32cr_table_h__
+#define __crc32cr_table_h__
+
+#define CRC32C_POLY 0x1EDC6F41
+#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
+
+unsigned long crc_c[256] =
+{
+0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+
+
+
+Stone, et. al. Standards Track [Page 11]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+};
+
+#endif
+
+ /* Example of table build routine */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define OUTPUT_FILE "crc32cr.h"
+#define CRC32C_POLY 0x1EDC6F41L
+FILE *tf;
+
+
+
+
+Stone, et. al. Standards Track [Page 12]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+unsigned long
+reflect_32 (unsigned long b)
+{
+ int i;
+ unsigned long rw = 0L;
+
+ for (i = 0; i < 32; i++){
+ if (b & 1)
+ rw |= 1 << (31 - i);
+ b >>= 1;
+ }
+ return (rw);
+}
+
+unsigned long
+build_crc_table (int index)
+{
+ int i;
+ unsigned long rb;
+
+ rb = reflect_32 (index);
+
+ for (i = 0; i < 8; i++){
+ if (rb & 0x80000000L)
+ rb = (rb << 1) ^ CRC32C_POLY;
+ else
+ rb <<= 1;
+ }
+ return (reflect_32 (rb));
+}
+
+main ()
+{
+ int i;
+
+ printf ("\nGenerating CRC-32c table file <%s>\n", OUTPUT_FILE);
+ if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
+ printf ("Unable to open %s\n", OUTPUT_FILE);
+ exit (1);
+ }
+ fprintf (tf, "#ifndef __crc32cr_table_h__\n");
+ fprintf (tf, "#define __crc32cr_table_h__\n\n");
+ fprintf (tf, "#define CRC32C_POLY 0x%08lX\n", CRC32C_POLY);
+ fprintf (tf, "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
+ fprintf (tf, "\nunsigned long crc_c[256] =\n{\n");
+ for (i = 0; i < 256; i++){
+ fprintf (tf, "0x%08lXL, ", build_crc_table (i));
+ if ((i & 3) == 3)
+
+
+
+Stone, et. al. Standards Track [Page 13]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ fprintf (tf, "\n");
+ }
+ fprintf (tf, "};\n\n#endif\n");
+
+ if (fclose (tf) != 0)
+ printf ("Unable to close <%s>." OUTPUT_FILE);
+ else
+ printf ("\nThe CRC-32c table has been written to <%s>.\n",
+ OUTPUT_FILE);
+}
+
+
+
+/* Example of crc insertion */
+
+#include "crc32cr.h"
+
+unsigned long
+generate_crc32c(unsigned char *buffer, unsigned int length)
+{
+ unsigned int i;
+ unsigned long crc32 = ~0L;
+ unsigned long result;
+ unsigned char byte0,byte1,byte2,byte3;
+
+ for (i = 0; i < length; i++){
+ CRC32C(crc32, buffer[i]);
+ }
+ result = ~crc32;
+
+ /* result now holds the negated polynomial remainder;
+ * since the table and algorithm is "reflected" [williams95].
+ * That is, result has the same value as if we mapped the message
+ * to a polynomial, computed the host-bit-order polynomial
+ * remainder, performed final negation, then did an end-for-end
+ * bit-reversal.
+ * Note that a 32-bit bit-reversal is identical to four inplace
+ * 8-bit reversals followed by an end-for-end byteswap.
+ * In other words, the bytes of each bit are in the right order,
+ * but the bytes have been byteswapped. So we now do an explicit
+ * byteswap. On a little-endian machine, this byteswap and
+ * the final ntohl cancel out and could be elided.
+ */
+
+ byte0 = result & 0xff;
+ byte1 = (result>>8) & 0xff;
+ byte2 = (result>>16) & 0xff;
+ byte3 = (result>>24) & 0xff;
+
+
+
+Stone, et. al. Standards Track [Page 14]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+ crc32 = ((byte0 << 24) |
+ (byte1 << 16) |
+ (byte2 << 8) |
+ byte3);
+ return ( crc32 );
+}
+
+int
+insert_crc32(unsigned char *buffer, unsigned int length)
+{
+ SCTP_message *message;
+ unsigned long crc32;
+ message = (SCTP_message *) buffer;
+ message->common_header.checksum = 0L;
+ crc32 = generate_crc32c(buffer,length);
+ /* and insert it into the message */
+ message->common_header.checksum = htonl(crc32);
+ return 1;
+}
+
+int
+validate_crc32(unsigned char *buffer, unsigned int length)
+{
+ SCTP_message *message;
+ unsigned int i;
+ unsigned long original_crc32;
+ unsigned long crc32 = ~0L;
+
+ /* save and zero checksum */
+ message = (SCTP_message *) buffer;
+ original_crc32 = ntohl(message->common_header.checksum);
+ message->common_header.checksum = 0L;
+ crc32 = generate_crc32c(buffer,length);
+ return ((original_crc32 == crc32)? 1 : -1);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 15]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+Authors' Addresses
+
+ Jonathan Stone
+ Room 446, Mail code 9040
+ Gates building 4A
+ Stanford, Ca 94305
+
+ EMail: jonathan@dsg.stanford.edu
+
+
+ Randall R. Stewart
+ 24 Burning Bush Trail.
+ Crystal Lake, IL 60012
+ USA
+
+ EMail: rrs@cisco.com
+
+
+ Douglas Otis
+ 800 E. Middlefield
+ Mountain View, CA 94043
+ USA
+
+ EMail: dotis@sanlight.net
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 16]
+
+RFC 3309 SCTP Checksum Change September 2002
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stone, et. al. Standards Track [Page 17]
+
diff --git a/doc/rfc3554.txt b/doc/rfc3554.txt
new file mode 100644
index 0000000..23ae9cd
--- /dev/null
+++ b/doc/rfc3554.txt
@@ -0,0 +1,507 @@
+
+
+
+
+
+
+Network Working Group S. Bellovin
+Request for Comments: 3554 J. Ioannidis
+Category: Standards Track AT&T Labs - Research
+ A. Keromytis
+ Columbia University
+ R. Stewart
+ Cisco
+ July 2003
+
+
+ On the Use of Stream Control Transmission Protocol (SCTP) with IPsec
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+Abstract
+
+ This document describes functional requirements for IPsec (RFC 2401)
+ and Internet Key Exchange (IKE) (RFC 2409) to facilitate their use in
+ securing SCTP (RFC 2960) traffic.
+
+1. Introduction
+
+ The Stream Control Transmission Protocol (SCTP) is a reliable
+ transport protocol operating on top of a connection-less packet
+ network such as IP. SCTP is designed to transport PSTN signaling
+ messages over IP networks, but is capable of broader applications.
+
+ When SCTP is used over IP networks, it may utilize the IP security
+ protocol suite [RFC2402][RFC2406] for integrity and confidentiality.
+ To dynamically establish IPsec Security Associations (SAs), a key
+ negotiation protocol such as IKE [RFC2409] may be used.
+
+ This document describes functional requirements for IPsec and IKE to
+ facilitate their use in securing SCTP traffic. In particular, we
+ discuss additional support in the form of a new ID type in IKE
+ [RFC2409] and implementation choices in the IPsec processing to
+ accommodate for the multiplicity of source and destination addresses
+ associated with a single SCTP association.
+
+
+
+Bellovin, et. al. Standards Track [Page 1]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+1.1. Terminology
+
+ In this document, the key words "MAY", "MUST, "MUST NOT", "optional",
+ "recommended", "SHOULD", and "SHOULD NOT", are to be interpreted as
+ described in [RFC-2119].
+
+2. SCTP over IPsec
+
+ When utilizing the Authentication Header [RFC2402] or Encapsulating
+ Security Payload [RFC2406] protocols to provide security services for
+ SCTP frames, the SCTP frame is treated as just another transport
+ layer protocol on top of IP (same as TCP, UDP, etc.)
+
+ IPsec implementations should already be able to use the SCTP
+ transport protocol number as assigned by IANA as a selector in their
+ Security Policy Database (SPD). It should be straightforward to
+ extend existing implementations to use the SCTP source and
+ destination port numbers as selectors in the SPD. Since the concept
+ of a port, and its location in the transport header is
+ protocol-specific, the IPsec code responsible for identifying the
+ transport protocol ports has to be suitably modified. This, however
+ is not enough to fully support the use of SCTP in conjunction with
+ IPsec.
+
+ Since SCTP can negotiate sets of source and destination addresses
+ (not necessarily in the same subnet or address range) that may be
+ used in the context of a single association, the SPD should be able
+ to accommodate this. The straightforward, and expensive, way is to
+ create one SPD entry for each pair of source/destination addresses
+ negotiated. A better approach is to associate sets of addresses with
+ the source and destination selectors in each SPD entry (in the case
+ of non-SCTP traffic, these sets would contain only one element).
+ While this is an implementation decision, implementors are encouraged
+ to follow this or a similar approach when designing or modifying the
+ SPD to accommodate SCTP-specific selectors.
+
+ Similarly, SAs may have multiple associated source and destination
+ addresses. Thus an SA is identified by the extended triplet ({set of
+ destination addresses}, SPI, Security Protocol). A lookup in the
+ Security Association Database (SADB) using the triplet (Destination
+ Address, SPI, Security Protocol), where Destination Address is any of
+ the negotiated peer addresses, MUST return the same SA.
+
+
+
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 2]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+3. SCTP and IKE
+
+ There are two issues relevant to the use of IKE when negotiating
+ protection for SCTP traffic:
+
+ a) Since SCTP allows for multiple source and destination network
+ addresses associated with an SCTP association, it MUST be possible
+ for IKE to efficiently negotiate these in the Phase 2 (Quick Mode)
+ exchange. The straightforward approach is to negotiate one pair of
+ IPsec SAs for each combination of source and destination addresses.
+ This can result in an unnecessarily large number of SAs, thus wasting
+ time (in negotiating these) and memory. All current implementations
+ of IKE support this functionality. However, a method for specifying
+ multiple selectors in Phase 2 is desirable for efficiency purposes.
+ Conformance with this document requires that implementations adhere
+ to the guidelines in the rest of this section.
+
+ Define a new type of ID, ID_LIST, that allows for recursive inclusion
+ of IDs. Thus, the IKE Phase 2 Initiator ID for an SCTP association
+ MAY be of type ID_LIST, which would in turn contain as many
+ ID_IPV4_ADDR IDs as necessary to describe Initiator addresses;
+ likewise for Responder IDs. Note that other selector types MAY be
+ used when establishing SAs for use with SCTP, if there is no need to
+ use negotiate multiple addresses for each SCTP endpoint (i.e., if
+ only one address is used by each peer of an SCTP flow).
+ Implementations MUST support this new ID type.
+
+ ID_LIST IDs cannot appear inside ID_LIST ID payloads. Any of the ID
+ types defined in [RFC2407] can be included inside an ID_LIST ID.
+ Each of the IDs contained in the ID_LIST ID must include a complete
+ Identification Payload header.
+
+ The following diagram illustrates the content of an ID_LIST ID
+ payload that contains two ID_FQDN payloads.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 3]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! ID Type ! Protocol ID ! Port !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! ID Type ! Protocol ID ! Port !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ~ FQDN 1 Identification Data ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! ID Type ! Protocol ID ! Port !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ~ FQDN 2 Identification Data ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The Next Payload field in any of the included IDs (for FQDN 1 and
+ FQDN 2) MUST be ignored by the Responder. The Payload Length, ID
+ Type, Protocol ID, and Port fields of the included Payloads should be
+ set to the appropriate values. The Protocol ID and Port fields of
+ the ID_LIST Payload should be set to zero by the Initiator and MUST
+ be ignored by the Responder.
+
+ Different types of IDs (e.g., an ID_FQDN and an ID_IPV4_ADDR) can be
+ included inside the same ID_LIST ID. If an ID type included in an
+ ID_LIST ID payload is invalid in the context the ID_LIST ID is used,
+ the whole ID_LIST should be considered to be at fault, e.g., if an
+ ID_LIST ID payload that contains an ID_FQDN and an ID_IPV4_ADDR is
+ received during an IKE Quick Mode exchange, the Responder should
+ signal a fault to the Initiator and stop processing of the message
+ (the same behavior it would exhibit if simply an ID_FQDN was received
+ instead).
+
+ The IANA-assigned number for the ID_LIST ID is 12.
+
+ b) For IKE to be able to validate the Phase 2 selectors, it must be
+ possible to exchange sufficient information during Phase 1.
+ Currently, IKE can directly accommodate the simple case of two peers
+ talking to each other, by using Phase 1 IDs corresponding to their IP
+ addresses, and encoding those same addresses in the SubjAltName of
+ the certificates used to authenticate the Phase 1 exchange. For more
+ complicated scenarios, external policy (or some other mechanism)
+ needs to be consulted, to validate the Phase 2 selectors and SA
+ parameters. All addresses presented in Phase 2 selectors MUST be
+ validated. That is, enough evidence must be presented to the
+
+
+
+Bellovin, et. al. Standards Track [Page 4]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+ Responder that the Initiator is authorized to receive traffic for all
+ addresses that appear in the Phase 2 selectors. This evidence can be
+ derived from the certificates exchanged during Phase 1 (if possible);
+ otherwise it must be acquired through out-of-band means (e.g., policy
+ mechanism, configured by the administrator, etc.).
+
+ In order to accommodate the same simple scenario in the context of
+ multiple source/destination addresses in an SCTP association, it MUST
+ be possible to:
+
+ 1) Specify multiple Phase 1 IDs, which are used to validate Phase
+ 2 parameters (in particular, the Phase 2 selectors). Following
+ the discussion on an ID_LIST ID type, it is possible to use the
+ same method for specifying multiple Phase 1 IDs.
+
+ 2) Authenticate the various Phase 1 IDs. Using pre-shared key
+ authentication, this is possible by associating the same shared
+ key with all acceptable peer Phase 1 IDs. In the case of
+ certificates, we have two alternatives:
+
+ a) The same certificate can contain multiple IDs encoded in
+ the SubjAltName field, as an ASN.1 sequence. Since this is
+ already possible, it is the preferred solution and any
+ conformant implementations MUST support this.
+
+ b) Multiple certificates MAY be passed during the Phase 1
+ exchange, in multiple CERT payloads. This feature is also
+ supported by the current specification. Since only one
+ signature may be issued per IKE Phase 1 exchange, it is
+ necessary for all certificates to contain the same key as
+ their Subject. However, this approach does not offer any
+ significant advantage over (a), thus implementations MAY
+ support it.
+
+ In either case, an IKE implementation needs to verify the
+ validity of a peer's claimed Phase 1 ID, for all such IDs
+ received over an exchange.
+
+ Although SCTP does not currently support modification of the
+ addresses associated with an SCTP association (while the latter is in
+ use), it is a feature that may be supported in the future. Unless
+ the set of addresses changes extremely often, it is sufficient to do
+ a full Phase 1 and Phase 2 exchange to establish the appropriate
+ selectors and SAs.
+
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 5]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+ The last issue with respect to SCTP and IKE pertains to the initial
+ offer of Phase 2 selectors (IDs) by the Initiator. Per the current
+ IKE specification, the Responder must send in the second message of
+ the Quick Mode the IDs received in the first message. Thus, it is
+ assumed that the Initiator already knows all the Selectors relevant
+ to this SCTP association. In most cases however, the Responder has
+ more accurate knowledge of its various addresses. Thus, the IPsec
+ Selectors established can be potentially insufficient or inaccurate.
+
+ If the proposed set of Selectors is not accurate from the Responder's
+ point of view, the latter can start a new Quick Mode exchange. In
+ this new Quick Mode exchange, the roles of Initiator and Responder
+ have been reversed; the new Initiator MUST copy the SA and Selectors
+ from the old Quick Mode message, and modify its set of Selectors to
+ match reality. All SCTP-supporting IKE implementations MUST be able
+ to do this.
+
+4. Security Considerations
+
+ This documents discusses the use of a security protocol (IPsec) in
+ the context of a new transport protocol (SCTP). SCTP, with its
+ provision for mobility, opens up the possibility for
+ traffic-redirection attacks whereby an attacker X claims that his
+ address should be added to an SCTP session between peers A and B, and
+ be used for further communications. In this manner, traffic between
+ A and B can be seen by X. If X is not in the communication path
+ between A and B, SCTP offers him new attack capabilities. Thus, all
+ such address updates of SCTP sessions should be authenticated. Since
+ IKE negotiates IPsec SAs for use by these sessions, IKE MUST validate
+ all addresses attached to an SCTP endpoint either through validating
+ the certificates presented to it during the Phase 1 exchange, or
+ through some out-of-band method.
+
+ The Responder in a Phase 2 exchange MUST verify the Initiator's
+ authority to receive traffic for all addresses that appear in the
+ Initiator's Phase 2 selectors. Not doing so would allow for any
+ valid peer of the Responder (i.e., anyone who can successfully
+ establish a Phase 1 SA with the Responder) to see any other valid
+ peer's traffic by claiming their address.
+
+5. IANA Considerations
+
+ IANA has assigned number 12 for ID_LIST (defined in Section 3) in the
+ "IPSEC Identification Type" registry from the Internet Security
+ Association and Key Management Protocol (ISAKMP) Identifiers table.
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 6]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+6. Intellectual Property Rights Notice
+
+ The IETF takes no position regarding the validity or scope of any
+ intellectual property or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; neither does it represent that it
+ has made any effort to identify any such rights. Information on the
+ IETF's procedures with respect to rights in standards-track and
+ standards-related documentation can be found in BCP-11. Copies of
+ claims of rights made available for publication and any assurances of
+ licenses to be made available, or the result of an attempt made to
+ obtain a general license or permission for the use of such
+ proprietary rights by implementors or users of this specification can
+ be obtained from the IETF Secretariat.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights which may cover technology that may be required to practice
+ this standard. Please address the information to the IETF Executive
+ Director.
+
+Normative References
+
+ [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the
+ Internet Protocol", RFC 2401, November 1998.
+
+ [RFC2402] Kent, S. and R. Atkinson, "IP Authentication Header", RFC
+ 2402, November 1998.
+
+ [RFC2406] Kent, S. and R. Atkinson, "IP Encapsulating Security
+ Payload (ESP)", RFC 2406, November 1998.
+
+ [RFC2407] Piper, D., "The Internet IP Security Domain of
+ Interpretation for ISAKMPD", RFC 2407, November 1998.
+
+ [RFC2408] Maughan, D., Schertler, M., Schneider, M. and J. Turner,
+ "Internet Security Association and Key Management
+ Protocol", RFC 2408, November 1998.
+
+ [RFC2409] Harkins, D. and D. Carrel, "The Internet Key Exchange
+ (IKE)", RFC 2409, November 1998.
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L. and V. Paxson, "Stream Control Transmission
+ Protocol", RFC 2960, October 2000.
+
+
+
+
+Bellovin, et. al. Standards Track [Page 7]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+Authors' Addresses
+
+ Steven M. Bellovin
+ AT&T Labs - Research
+ 180 Park Avenue
+ Florham Park, New Jersey 07932-0971
+
+ Phone: +1 973 360 8656
+ EMail: smb@research.att.com
+
+
+ John Ioannidis
+ AT&T Labs - Research
+ 180 Park Avenue
+ Florham Park, New Jersey 07932-0971
+
+ EMail: ji@research.att.com
+
+
+ Angelos D. Keromytis
+ Columbia University, CS Department
+ 515 CS Building
+ 1214 Amsterdam Avenue, Mailstop 0401
+ New York, New York 10027-7003
+
+ Phone: +1 212 939 7095
+ EMail: angelos@cs.columbia.edu
+
+
+ Randall R. Stewart
+ 24 Burning Bush Trail.
+ Crystal Lake, IL 60012
+
+ Phone: +1-815-477-2127
+ EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 8]
+
+RFC 3554 SCTP with IPsec July 2003
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assignees.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bellovin, et. al. Standards Track [Page 9]
+
diff --git a/doc/rfc3758.txt b/doc/rfc3758.txt
new file mode 100644
index 0000000..1c0dc15
--- /dev/null
+++ b/doc/rfc3758.txt
@@ -0,0 +1,1235 @@
+
+
+
+
+
+
+Network Working Group R. Stewart
+Request for Comments: 3758 M. Ramalho
+Category: Standards Track Cisco Systems, Inc.
+ Q. Xie
+ Motorola, Inc.
+ M. Tuexen
+ Univ. of Applied Sciences Muenster
+ P. Conrad
+ University of Delaware
+ May 2004
+
+
+ Stream Control Transmission Protocol (SCTP)
+ Partial Reliability Extension
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2004). All Rights Reserved.
+
+Abstract
+
+ This memo describes an extension to the Stream Control Transmission
+ Protocol (SCTP) that allows an SCTP endpoint to signal to its peer
+ that it should move the cumulative ack point forward. When both
+ sides of an SCTP association support this extension, it can be used
+ by an SCTP implementation to provide partially reliable data
+ transmission service to an upper layer protocol. This memo describes
+ the protocol extensions, which consist of a new parameter for INIT
+ and INIT ACK, and a new FORWARD TSN chunk type, and provides one
+ example of a partially reliable service that can be provided to the
+ upper layer via this mechanism.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 1]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 1.1. Overview of Protocol Extensions. . . . . . . . . . . . . 2
+ 1.2. Overview of New Services Provided to the Upper Layer . . 3
+ 1.3. Benefits of PR-SCTP . . . . . . . . . . . . . . . . . . 4
+ 2. Conventions. . . . . . . . . . . . . . . . . . . . . . . . . . 5
+ 3. Protocol Changes to support PR-SCTP . . . . . . . . . . . . . 5
+ 3.1. Forward-TSN-Supported Parameter For INIT and INIT ACK. . 5
+ 3.2. Forward Cumulative TSN Chunk Definition (FORWARD TSN). . 5
+ 3.3. Negotiation of Forward-TSN-Supported parameter . . . . . 7
+ 3.3.1. Sending Forward-TSN-Supported param in INIT . . . 7
+ 3.3.2. Receipt of Forward-TSN-Supported parameter in
+ INIT or INIT-ACK. . . . . . . . . . . . . . . . . 7
+ 3.3.3. Receipt of Op. Error for Forward-TSN-Supported
+ Param . . . . . . . . . . . . . . . . . . . . . . 8
+ 3.4. Definition of "abandoned" in the context of PR-SCTP. . . 8
+ 3.5. Sender Side Implementation of PR-SCTP. . . . . . . . . . 9
+ 3.6. Receiver Side Implementation of PR-SCTP. . . . . . . . . 12
+ 4. Services provided by PR-SCTP to the upper layer. . . . . . . . 14
+ 4.1. PR-SCTP Service Definition for "timed reliability" . . . 15
+ 4.2. PR-SCTP Association Establishment. . . . . . . . . . . . 16
+ 4.3. Guidelines for defining other PR-SCTP Services . . . . . 17
+ 4.4. Usage Notes. . . . . . . . . . . . . . . . . . . . . . . 19
+ 5. Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . 19
+ 6. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 19
+ 7. Security Considerations. . . . . . . . . . . . . . . . . . . . 19
+ 8. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 20
+ 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 20
+ 9.1. Normative References . . . . . . . . . . . . . . . . . . 20
+ 9.2. Informative References . . . . . . . . . . . . . . . . . 20
+ 10. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 20
+ 11. Full Copyright Statement . . . . . . . . . . . . . . . . . . .
+
+1. Introduction
+
+ This memo describes an extension to the Stream Control Transmission
+ Protocol (SCTP) RFC 2960 [2] that allows an SCTP sender to signal to
+ its peer that it should no longer expect to receive one or more DATA
+ chunks.
+
+1.1. Overview of Protocol Extensions
+
+ The protocol extension described in this document consists of two new
+ elements:
+
+ 1. a single new parameter in the INIT/INIT-ACK exchange that
+ indicates whether the endpoint supports the extension
+
+
+
+Stewart, et al. Standards Track [Page 2]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ 2. a single new chunk type, FORWARD TSN, that indicates that the
+ receiver should move its cumulative ack point forward (possibly
+ skipping past one or more DATA chunks that may not yet have been
+ received and/or acknowledged.)
+
+1.2. Overview of New Services Provided to the Upper Layer
+
+ When this extension is supported by both sides of an SCTP
+ association, it can be used to provide partially reliable transport
+ service over an SCTP association. We define partially reliable
+ transport service as a service that allows the user to specify, on a
+ per message basis, the rules governing how persistent the transport
+ service should be in attempting to send the message to the receiver.
+
+ One example of partially reliable service is specified in this
+ document, namely a "timed reliability" service. This service allows
+ the service user to indicate a limit on the duration of time that the
+ sender should try to transmit/retransmit the message (this is a
+ natural extension of the "lifetime" parameter already in the base
+ protocol).
+
+ In addition to this example, we will also show that defining the
+ semantics of a particular partially reliable service involves two
+ elements, namely:
+
+ 1. how the service user indicates the level of reliability required
+ for a particular message, and
+
+ 2. how the sender side implementation uses that reliability level to
+ determine when to give up on further retransmissions of that
+ message.
+
+ Note that other than the fact that the FORWARD-TSN chunk is required,
+ neither of these two elements impacts the "on-the-wire" protocol;
+ only the API and the sender side implementation are affected by the
+ way in which the service is defined to the upper layer. Therefore,
+ in principle, it is feasible to implement many varieties of partially
+ reliable services in a particular SCTP implementation without
+ changing the on-the-wire protocol. Also, the SCTP receiver does not
+ necessarily need to know which semantics of partially reliable
+ service are being used by the sender, since the receiver's only role
+ is to correctly interpret FORWARD TSN chunks, thereby skipping past
+ messages that the sender has decided to no longer transmit (or
+ retransmit).
+
+ Nevertheless, it is recommended that a limited number of standard
+ definitions of partially reliable services be standardized by the
+ IETF so that the designers of IETF application layer protocols can
+
+
+
+Stewart, et al. Standards Track [Page 3]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ match the requirements of their upper layer protocols to standard
+ service definitions provided by a particular SCTP implementation.
+ One such definition, "timed reliability", is included in this
+ document. Given the extensions proposed in this document, other
+ definitions may be standardized as the need arises without further
+ changes to the on-the-wire protocol.
+
+1.3. Benefits of PR-SCTP
+
+ Hereafter, we use the notation "Partial Reliable Stream Control
+ Transmission Protocol (PR-SCTP)" to refer to the SCTP protocol,
+ extended as defined in this document.
+
+ The following are some of the advantages for integrating partially
+ reliable data service into SCTP, i.e., benefits of PR-SCTP:
+
+ 1. Some application layer protocols may benefit from being able to
+ use a single SCTP association to carry both reliable content, --
+ such as text pages, billing and accounting information, setup
+ signaling -- and unreliable content, e.g., state that is highly
+ sensitive to timeliness, where generating a new packet is more
+ advantageous than transmitting an old one [3].
+
+ 2. Partially reliable data traffic carried by PR-SCTP will enjoy the
+ same communication failure detection and protection capabilities
+ as the normal reliable SCTP data traffic does. This includes the
+ ability to quickly detect a failed destination address, fail-over
+ to an alternate destination address, and be notified if the data
+ receiver becomes unreachable.
+
+ 3. In addition to providing unordered, unreliable data transfer as
+ UDP does, PR-SCTP can provide ordered, unreliable data transfer
+ service.
+
+ 4. PR-SCTP employs the same congestion control and congestion
+ avoidance for all data traffic, whether reliable or partially
+ reliable - this is very desirable since SCTP enforces TCP-
+ friendliness (unlike UDP.)
+
+ 5. Because of the chunk bundling function of SCTP, reliable and
+ unreliable messages can be multiplexed over a single PR-SCTP
+ association. Therefore, the number of IP datagrams (and hence the
+ network overhead) can be reduced instead of having to send these
+ different types of data using separate protocols. Additionally,
+ this multiplexing allows for port savings versus using different
+ ports for reliable and unreliable connections.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 4]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+2. Conventions
+
+ The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+ SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+ they appear in this document, are to be interpreted as described in
+ BCP 14, RFC 2119 [1].
+
+ Comparisons and arithmetic on Transport Sequence Numbers (TSNs) are
+ governed by the rules in Section 1.6 of RFC 2960 [2].
+
+3. Protocol Changes to support PR-SCTP
+
+3.1. Forward-TSN-Supported Parameter For INIT and INIT ACK
+
+ The following new OPTIONAL parameter is added to the INIT and INIT
+ ACK chunks.
+
+ Parameter Name Status Type Value
+ -------------------------------------------------------------
+ Forward-TSN-Supported OPTIONAL 49152 (0xC000)
+
+ At the initialization of the association, the sender of the INIT or
+ INIT ACK chunk MAY include this OPTIONAL parameter to inform its peer
+ that it is able to support the Forward TSN chunk (see Section 3.3 for
+ further details). The format of this parameter is defined as
+ follows:
+
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 49152 | Parameter Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Type: 16 bit u_int
+
+ 49152, indicating Forward-TSN-Supported parameter
+
+ Length: 16 bit u_int
+
+ Indicates the size of the parameter, i.e., 4.
+
+3.2 Forward Cumulative TSN Chunk Definition (FORWARD TSN)
+
+ The following new chunk type is defined:
+
+ Chunk Type Chunk Name
+ ------------------------------------------------------
+ 192 (0xC0) Forward Cumulative TSN (FORWARD TSN)
+
+
+
+
+Stewart, et al. Standards Track [Page 5]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ This chunk shall be used by the data sender to inform the data
+ receiver to adjust its cumulative received TSN point forward because
+ some missing TSNs are associated with data chunks that SHOULD NOT be
+ transmitted or retransmitted by the sender.
+
+ Forward Cumulative TSN chunk has the following format:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 192 | Flags = 0x00 | Length = Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | New Cumulative TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream-1 | Stream Sequence-1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream-N | Stream Sequence-N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags:
+
+ Set to all zeros on transmit and ignored on receipt.
+
+ New Cumulative TSN: 32 bit u_int
+
+ This indicates the new cumulative TSN to the data receiver. Upon
+ the reception of this value, the data receiver MUST consider
+ any missing TSNs earlier than or equal to this value as received,
+ and stop reporting them as gaps in any subsequent SACKs.
+
+ Stream-N: 16 bit u_int
+
+ This field holds a stream number that was skipped by this
+ FWD-TSN.
+
+ Stream Sequence-N: 16 bit u_int
+
+ This field holds the sequence number associated with the stream
+ that was skipped. The stream sequence field holds the largest
+ stream sequence number in this stream being skipped. The receiver
+ of the FWD-TSN's can use the Stream-N and Stream Sequence-N fields
+ to enable delivery of any stranded TSN's that remain on the stream
+ re-ordering queues. This field MUST NOT report TSN's corresponding
+ to DATA chunks that are marked as unordered. For ordered DATA
+ chunks this field MUST be filled in.
+
+
+
+Stewart, et al. Standards Track [Page 6]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+3.3. Negotiation of Forward-TSN-Supported parameter
+
+3.3.1. Sending Forward-TSN-Supported param in INIT
+
+ If an SCTP endpoint supports the FORWARD TSN chunk, then any time it
+ sends an INIT during association establishment, it MAY include the
+ Forward-TSN-supported parameter in the INIT chunk to indicate this
+ fact to its peer.
+
+ Note that if the endpoint chooses NOT to include the parameter, then
+ at no time during the life of the association can it send or process
+ a FORWARD TSN. It MUST instead act as if it does NOT support the
+ FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any
+ FORWARD TSN.
+
+3.3.2. Receipt of Forward-TSN-Supported parameter in INIT or INIT-ACK
+
+ When a receiver of an INIT detects a Forward-TSN-Supported parameter
+ and does not support the Forward-TSN chunk type, the receiver MUST
+ follow the rules defined in Section 3.3.3 of RFC 2960 [2].
+
+ When a receiver of an INIT-ACK detects a Forward-TSN-Supported
+ parameter and it does not support the Forward-TSN chunk type, the
+ receiver MUST follow the rules defined in Section 3.3.3 of RFC 2960
+ [2].
+
+ When a receiver of an INIT detects a Forward-TSN-Supported parameter
+ and it does support the Forward-TSN chunk type, the receiver MAY
+ respond with a Forward-TSN-supported parameter in the INIT-ACK chunk.
+
+ Note that if the endpoint chooses NOT to include the parameter, then
+ at no time during the life of the association can it send or process
+ a FORWARD TSN. It MUST instead act as if it does NOT support the
+ FORWARD TSN chunk, returning an ERROR to the peer upon receipt of any
+ FORWARD TSN.
+
+ When an endpoint that supports the FORWARD TSN chunk receives an INIT
+ that does not contain the Forward-TSN-Supported Parameter, that
+ endpoint:
+
+ o MAY include the Forward-TSN-Supported parameter in the INIT-ACK,
+ o SHOULD record the fact that the peer does not support the FORWARD
+ TSN chunk,
+ o MUST NOT send a FORWARD TSN chunk at any time during the
+ associations life,
+ o SHOULD inform the upper layer if the upper layer has requested
+ such notification.
+
+
+
+
+Stewart, et al. Standards Track [Page 7]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+3.3.3. Receipt of Op. Error for Forward-TSN-Supported Param
+
+ When an SCTP endpoint that desires to use the FORWARD TSN chunk
+ feature for partially reliable data transfer receives an operational
+ error from the remote endpoint (either bundled with the COOKIE or as
+ an unrecognized parameter in the INIT-ACK), indicating that the
+ remote endpoint does not recognize the Forward-TSN-Supported
+ parameter, the local endpoint SHOULD inform its upper layer of the
+ remote endpoint's inability to support partially reliable data
+ transfer.
+
+ The local endpoint may then choose to either:
+
+ 1) end the initiation process (in cases where the initiation process
+ has already ended, the endpoint may need to send an ABORT) in
+ consideration of the peer's inability to supply the requested
+ features for the new association, or
+
+ 2) continue the initiation process (in cases where the initiation
+ process has already completed, the endpoint MUST just mark the
+ association as not supporting partial reliability), but with the
+ understanding that partially reliable data transmission is not
+ supported. In this case, the endpoint receiving the operational
+ error SHOULD note that the FORWARD TSN chunk is not supported, and
+ MUST NOT transmit a FORWARD TSN chunk at any time during the life
+ of the association.
+
+3.4. Definition of "abandoned" in the context of PR-SCTP
+
+ At some point, a sending PR-SCTP implementation MAY determine that a
+ particular data chunk SHOULD NOT be transmitted or retransmitted
+ further, in accordance with the rules governing some particular PR-
+ SCTP service definition (such as the definition of "timed
+ reliability" in Section 4.1.) For purposes of this document, we
+ define the term "abandoned" to refer to any data chunk about which
+ the SCTP sender has made this determination.
+
+ Each PR-SCTP service defines the rules for determining when a TSN is
+ "abandoned", and accordingly, the rules that govern how, whether, and
+ when to "abandon" a TSN may vary from one service definition to
+ another. However, the rules governing the actions taken when a TSN
+ is "abandoned" do NOT vary between service definitions; these rules
+ are included in Section 3.5.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 8]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+3.5. Sender Side Implementation of PR-SCTP
+
+ The sender side implementation of PR-SCTP is identical to that of the
+ base SCTP protocol, except for:
+
+ o actions a sending side PR-SCTP implementation must take when a TSN
+ is "abandoned" (as per the rules of whatever PR-SCTP service
+ definition is in effect)
+ o special actions that a PR-SCTP implementation must take upon
+ receipt of SACK
+ o rules governing the generation of FORWARD TSN chunks.
+
+ In detail, these exceptions are as follows:
+
+ A1) The sender maintains an "Advanced.Peer.Ack.Point" for each peer
+ to track a theoretical cumulative TSN point of the peer (Note,
+ this is a _new_ protocol variable and its value is NOT
+ necessarily the same as the SCTP "Cumulative TSN Ack Point" as
+ defined in Section 1.4 of RFC 2960 [2], and as discussed
+ throughout that document.)
+
+ A2) From time to time, as governed by the rules of a particular PR-
+ SCTP service definition (see Section 4), the SCTP data sender may
+ make a determination that a particular data chunk that has
+ already been assigned a TSN SHOULD be "abandoned".
+
+ When a data chunk is "abandoned", the sender MUST treat the data
+ chunk as being finally acked and no longer outstanding.
+
+ The sender MUST NOT credit an "abandoned" data chunk to the
+ partial_bytes_acked as defined in Section 7.2.2 of RFC 2960 [2],
+ and MUST NOT advance the cwnd based on this "abandoned" data
+ chunk.
+
+ A3) When a TSN is "abandoned", if it is part of a fragmented message,
+ all other TSN's within that fragmented message MUST be abandoned
+ at the same time.
+
+ A4) Whenever the data sender receives a SACK from the data receiver,
+ it MUST first process the SACK using the normal procedures as
+ defined in Section 6.2.1 of RFC 2960 [2].
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 9]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ The data sender MUST then perform the following additional steps:
+
+ C1) Let SackCumAck be the Cumulative TSN ACK carried in the
+ received SACK.
+
+ If (Advanced.Peer.Ack.Point < SackCumAck), then update
+ Advanced.Peer.Ack.Point to be equal to SackCumAck.
+
+ C2) Try to further advance the "Advanced.Peer.Ack.Point" locally,
+ that is, to move "Advanced.Peer.Ack.Point" up as long as the
+ chunk next in the out-queue space is marked as "abandoned",
+ as shown in the following example:
+
+ Assuming that a SACK arrived with the Cumulative TSN ACK =
+ 102 and the Advanced.Peer.Ack.Point is updated to this
+ value:
+
+ out-queue at the end of ==> out-queue after Adv.Ack.Point
+ normal SACK processing local advancement
+
+ ... ...
+ Adv.Ack.Pt-> 102 acked 102 acked
+ 103 abandoned 103 abandoned
+ 104 abandoned Adv.Ack.P-> 104 abandoned
+ 105 105
+ 106 acked 106 acked
+ ... ...
+
+ In this example, the data sender successfully advanced the
+ "Advanced.Peer.Ack.Point" from 102 to 104 locally.
+
+ C3) If, after step C1 and C2, the "Advanced.Peer.Ack.Point" is
+ greater than the Cumulative TSN ACK carried in the received
+ SACK, the data sender MUST send the data receiver a FORWARD
+ TSN chunk containing the latest value of the
+ "Advanced.Peer.Ack.Point". Note that the sender MAY delay
+ the sending of a FORWARD TSN as defined in rule F2 below.
+ IMPLEMENTATION NOTE: It is an implementation decision as to
+ which destination address it is to be sent to, the only
+ restriction being that the address MUST be one that is
+ CONFIRMED.
+
+ C4) For each "abandoned" TSN, the sender of the FORWARD TSN MUST
+ determine if the chunk has a valid stream and sequence number
+ (i.e., it was ordered). If the chunk has a valid stream and
+ sequence number, the sender MUST include the stream and
+ sequence number in the FORWARD TSN. This information will
+ enable the receiver to easily find any stranded TSN's waiting
+
+
+
+Stewart, et al. Standards Track [Page 10]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ on stream reorder queues. Each stream SHOULD only be
+ reported once; this means that if multiple abandoned messages
+ occur in the same stream, then only the highest abandoned
+ stream sequence number is reported. If the total size of the
+ FORWARD TSN does NOT fit in a single MTU, then the sender of
+ the FORWARD TSN SHOULD lower the Advanced.Peer.Ack.Point to
+ the last TSN that will fit in a single MTU.
+
+ C5) If a FORWARD TSN is sent, the sender MUST assure that at
+ least one T3-rtx timer is running. IMPLEMENTATION NOTE: Any
+ destination's timer may be used for the purposes of rule C5.
+
+ A5) Any time the T3-rtx timer expires, on any destination, the sender
+ SHOULD try to advance the "Advanced.Peer.Ack.Point" by following
+ the procedures outlined in C2 - C5.
+
+ The following additional rules govern the generation of FORWARD TSN
+ chunks:
+
+ F1) An endpoint MUST NOT use the FORWARD TSN for any purposes other
+ than circumstances described in this document.
+
+ F2) The data sender SHOULD always attempt to bundle an outgoing
+ FORWARD TSN with outbound DATA chunks for efficiency.
+
+ A sender MAY even choose to delay the sending of the FORWARD TSN
+ in the hope of bundling it with an outbound DATA chunk.
+
+ IMPLEMENTATION NOTE: An implementation may wish to limit the
+ number of duplicate FORWARD TSN chunks it sends by either only
+ sending a duplicate FORWARD TSN every other SACK or waiting a
+ full RTT before sending a duplicate FORWARD TSN.
+
+ IMPLEMENTATION NOTE: An implementation may allow the maximum
+ delay for generating a FORWARD TSN to be configured either
+ statically or dynamically in order to meet the specific timing
+ requirements of the protocol being carried, but see the next
+ rule:
+
+ F3) Any delay applied to the sending of FORWARD TSN chunk SHOULD NOT
+ exceed 200ms and MUST NOT exceed 500ms. In other words, an
+ implementation MAY lower this value below 500ms but MUST NOT
+ raise it above 500ms.
+
+ NOTE: Delaying the sending of FORWARD TSN chunks may cause delays
+ in the receiver's ability to deliver other data being held at the
+ receiver for re-ordering. The values of 200ms and 500ms match
+
+
+
+
+Stewart, et al. Standards Track [Page 11]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ the required values for the delayed acknowledgement in RFC 2960
+ [2] since delaying a FORWARD TSN has the same consequences but in
+ the reverse direction.
+
+ F4) The detection criterion for out-of-order SACKs MUST remain the
+ same as stated in RFC 2960, that is, a SACK is only considered
+ out-of-order if the Cumulative TSN ACK carried in the SACK is
+ earlier than that of the previous received SACK (i.e., the
+ comparison MUST NOT be made against "Advanced.Peer.Ack.Point").
+
+ F5) If the decision to "abandon" a chunk is made, no matter how such
+ a decision is made, the appropriate congestion adjustment MUST be
+ made as specified in RFC 2960 if the chunk would have been marked
+ for retransmission later (e.g., either by T3-Timeout or by Fast
+ Retransmit).
+
+3.6. Receiver Side Implementation of PR-SCTP
+
+ The receiver side implementation of PR-SCTP at an SCTP endpoint A is
+ capable of supporting any PR-SCTP service definition used by the
+ sender at endpoint B, even if that service definition is not
+ supported by the sending side functionality of host A. All that is
+ necessary is that the receiving side correctly handle the Forward-
+ TSN-Supported parameter as specified in Section 3.3, and correctly
+ handle the receipt of FORWARD TSN chunks as specified below.
+
+ DATA chunk arrival at a PR-SCTP receiver proceeds exactly as for DATA
+ chunk arrival at a base protocol SCTP receiver---that is, the
+ receiver MUST perform the same TSN handling, including duplicate
+ detection, gap detection, SACK generation, cumulative TSN
+ advancement, etc. as defined in RFC 2960 [2]---with the following
+ exceptions and additions.
+
+ When a FORWARD TSN chunk arrives, the data receiver MUST first update
+ its cumulative TSN point to the value carried in the FORWARD TSN
+ chunk, and then MUST further advance its cumulative TSN point locally
+ if possible, as shown by the following example:
+
+ Assuming that the new cumulative TSN carried in the arrived
+ FORWARD TSN is 103:
+
+ in-queue before processing in-queue after processing
+ the FORWARD TSN ==> the FORWARD TSN and further
+ advancement
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 12]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ cum.TSN.Pt-> 102 received 102 --
+ 103 missing 103 --
+ 104 received 104 --
+ 105 received cum.TSN.Pt-> 105 received
+ 106 missing 106 missing
+ 107 received 107 received
+ ... ...
+
+ In this example, the receiver's cumulative TSN point is first
+ updated to 103 and then further advanced to 105.
+
+ After the above processing, the data receiver MUST stop reporting any
+ missing TSNs earlier than or equal to the new cumulative TSN point.
+
+ Note, if the "New Cumulative TSN" value carried in the arrived
+ FORWARD TSN chunk is found to be behind or at the current cumulative
+ TSN point, the data receiver MUST treat this FORWARD TSN as out-of-
+ date and MUST NOT update its Cumulative TSN. The receiver SHOULD
+ send a SACK to its peer (the sender of the FORWARD TSN) since such a
+ duplicate may indicate the previous SACK was lost in the network.
+
+ Any time a FORWARD TSN chunk arrives, for the purposes of sending a
+ SACK, the receiver MUST follow the same rules as if a DATA chunk had
+ been received (i.e., follow the delayed sack rules specified in RFC
+ 2960 [2] section 6.2).
+
+ Whenever a DATA chunk arrives with the 'U' bit set to '0' (indicating
+ ordered delivery) and is out of order, the receiver must hold the
+ chunk for reordering. Since it is possible with PR-SCTP that a DATA
+ chunk being waited upon will not be retransmitted, special actions
+ will need to be taken upon the arrival of a FORWARD TSN.
+
+ In particular, during processing of a FORWARD TSN, the receiver MUST
+ use the stream sequence information to examine all of the listed
+ stream reordering queues, and immediately make available for delivery
+ stream sequence numbers earlier than or equal to the stream sequence
+ number listed inside the FORWARD TSN. Any such stranded data SHOULD
+ be made immediately available to the upper layer application.
+
+ An application using PR-SCTP receiving data should be aware of
+ possible missing messages. The stream sequence number can be used,
+ in such a case, to determine that an intervening message has been
+ skipped. When intervening messages are missing, it is an application
+ decision to process the messages or to take some other corrective
+ action.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 13]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ After receiving and processing a FORWARD TSN, the data receiver MUST
+ take cautions in updating its re-assembly queue. The receiver MUST
+ remove any partially reassembled message, which is still missing one
+ or more TSNs earlier than or equal to the new cumulative TSN point.
+ In the event that the receiver has invoked the partial delivery API,
+ a notification SHOULD also be generated to inform the upper layer API
+ that the message being partially delivered will NOT be completed.
+
+ Note that after receiving a FORWARD TSN and updating the cumulative
+ acknowledgement point, if a TSN that was skipped does arrive (i.e.,
+ due to network reordering), then the receiver will follow the normal
+ rules defined in RFC 2960 [2] for handling duplicate data. This
+ implies that the receiver will drop the chunk and report it as a
+ duplicate in the next outbound SACK chunk.
+
+4. Services provided by PR-SCTP to the upper layer
+
+ As described in Section 1.2, it is feasible to implement a variety of
+ partially reliable transport services using the new protocol
+ mechanisms introduced in Section 3; introducing these new services
+ requires making changes only at the sending side API, and the sending
+ side protocol implementation. Thus, there may be a temptation to
+ standardize only the protocol, and leave the service definition as
+ "implementation specific" or leave it to be defined in
+ "informational" documents.
+
+ However, for those who may wish to write IETF standards for upper
+ layer protocols implemented over PR-SCTP, it is important to be able
+ to refer to a standard definition of services provided. Therefore,
+ this section provides example definitions of one such service, while
+ also providing guidelines for the definition of additional services
+ as required. Each such service may be proposed as a separate new
+ RFC.
+
+ Section 4 is organized as follows:
+
+ o Section 4.1 provides the definition of one specific PR-SCTP
+ service: timed reliability.
+
+ o Section 4.2 describes how a particular PR-SCTP service definition
+ is requested by the upper layer during association establishment,
+ and how the upper layer is notified if that request cannot be
+ satisfied.
+
+ o Section 4.3 then provides guidelines for the specification of PR-
+ SCTP services other then the one defined in this memo.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 14]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ o Finally, Section 4.4 describes some additional usage notes that
+ upper layer protocol designers and implementors may find helpful.
+
+4.1. PR-SCTP Service Definition for "timed reliability"
+
+ The "timed reliability" service is a natural extension of the
+ "lifetime" concept already present in the base SCTP protocol.
+
+ When this service is requested for an SCTP association, it changes
+ the meaning of the lifetime parameter specified in the SEND primitive
+ (see Section 10.1, part (E) of RFC 2960 [2]; note that the parameter
+ is spelled "life time" in that document.)
+
+ In the base SCTP protocol, the lifetime parameter is used to avoid
+ sending stale data. When a lifetime value is indicated for a
+ particular message and that lifetime expires, SCTP cancels the
+ sending of this message, and notifies the ULP if the first
+ transmission of the data does not take place (because of rwnd or cwnd
+ limitations, or for any other reason). However, in the base
+ protocol, if SCTP has sent the first transmission before the lifetime
+ expires, then the message MUST be sent as a normal reliable message.
+ During episodes of congestion this is particularly unfortunate, as
+ retransmission wastes bandwidth that could have been used for other
+ (non-lifetime expired) messages.
+
+ When the "timed reliability" service is invoked, this latter
+ restriction is removed. Specifically, when the "timed reliability"
+ service is in effect, the following rules govern all messages that
+ are sent with a lifetime parameter:
+
+ TR1) If the lifetime parameter of a message is SCTP_LIFETIME_RELIABLE
+ (or unspecified see Section 5), that message is treated as a
+ normal reliable SCTP message, just as in the base SCTP protocol.
+
+ TR2) If the lifetime parameter is not SCTP_LIFETIME_RELIABLE (see
+ Section 5), then the SCTP sender MUST treat the message just as
+ if it were a normal reliable SCTP message, as long as the
+ lifetime has not yet expired.
+
+ TR3) Before assigning a TSN to any message, the SCTP sender MUST
+ evaluate the lifetime of that message. If it is expired, the
+ SCTP sender MUST NOT assign a TSN to that message, but instead,
+ SHOULD issue a notification to the upper layer and abandon the
+ message.
+
+ TR4) Before transmitting or retransmitting a message for which a TSN
+ is already assigned, the SCTP sender MUST evaluate the lifetime
+ of the message. If the lifetime of the message is expired, the
+
+
+
+Stewart, et al. Standards Track [Page 15]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ SCTP sender MUST "abandon" the message, as per the rules
+ specified in Section 3.5 marking that TSN as eligible for
+ forward TSN. Note that this meets the requirement G1 defined in
+ Section 4.3. IMPLEMENTATION NOTE: An implementation SHOULD
+ delay TSN assignment as mentioned in RFC 2960 [2] Section 10.1.
+ In such a case, the lifetime parameter should be checked BEFORE
+ assigning a TSN, thus allowing a message to be abandoned without
+ the need to send a FORWARD TSN.
+
+ TR5) The sending SCTP MAY evaluate the lifetime of messages at
+ anytime. Expired messages that have not been assigned a TSN MAY
+ be handled as per rule TR3. Expired messages that HAVE been
+ assigned a TSN MAY be handled as per rule TR4.
+
+ TR6) The sending application MUST NOT change the lifetime parameter
+ once the message is passed to the sending SCTP.
+
+ Implementation Note: Rules TR1 through TR4 are designed in such a way
+ as to avoid requiring the implementer to maintain a separate timer
+ for each message; instead, the lifetime need only be evaluated at
+ points in the life of the message where actions are already being
+ taken, such as TSN assignment, transmission, or expiration of a
+ retransmission timeout. Rule TR5 is intended to give the SCTP
+ implementor flexibility to evaluate lifetime at any other convenient
+ opportunity, WITHOUT requiring that lifetime be evaluated immediately
+ at the point in time where it expires.
+
+4.2. PR-SCTP Association Establishment
+
+ An upper layer protocol (ULP) that uses PR-SCTP may need to know
+ whether PR-SCTP can be supported on a given association. Therefore,
+ the ULP needs to have some indication of whether the FORWARD-TSN
+ chunk is supported by its peer.
+
+ Section 10.1 of RFC 2960 [2] describes abstract primitives for the
+ ULP-to-SCTP interface, while noting that "individual implementations
+ must define their own exact format, and may provide combinations or
+ subsets of the basic functions in single calls."
+
+ In this section, we describe one additional return value that may be
+ added to the ASSOCIATE primitive to allow an SCTP service user to
+ indicate whether the FORWARD-TSN chunk is supported by its peer.
+
+ RFC 2960 indicates that the ASSOCIATE primitive "allows the upper
+ layer to initiate an association to a specific peer endpoint". It is
+ structured as follows:
+
+
+
+
+
+Stewart, et al. Standards Track [Page 16]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ Format: ASSOCIATE(local SCTP instance name, destination transport
+ addr, outbound stream count)
+ -> association id [,destination transport addr list]
+ [,outbound stream count]
+
+ This extension adds one new OPTIONAL return value, such that the new
+ primitive reads as follows:
+
+ Format: ASSOCIATE(local SCTP instance name, destination transport
+ addr, outbound stream count )
+ -> association id [,destination transport addr list]
+ [,outbound stream count] [,forward tsn supported]
+
+ NOTE: As per RFC 2960, if the ASSOCIATE primitive is implemented as a
+ non-blocking call, the new OPTIONAL return value shall be passed with
+ the association parameters using the COMMUNICATION UP notification.
+
+ The new OPTIONAL parameter "forward tsn supported" is a boolean flag:
+
+ (0) false [default] indicates that FORWARD TSN is not enabled by both
+ endpoints.
+
+ (1) true indicates that FORWARD TSN is enabled on both endpoints.
+
+ We also add a new primitive to allow the user application to enable/
+ disable the PR-SCTP service on its endpoint before an association is
+ established.
+
+ Format: ENABLE_PRSCTP(local SCTP instance name, boolean enable)
+
+ The boolean parameter enable, if set to true, will enable PR-SCTP
+ upon future endpoint associations. If the boolean parameter is set
+ to false, then the local endpoint will not advertise support of PR-
+ SCTP and thus disable the feature on future associations. It is
+ recommended that this option be disabled by default, i.e., in order
+ to enable PR-SCTP, the user will need to call this API option with
+ the enable flag set to "true".
+
+4.3. Guidelines for defining other PR-SCTP Services
+
+ Other PR-SCTP services may be defined and implemented as dictated by
+ the needs of upper layer protocols. If such upper layer protocols
+ are to be standardized and require some particular PR-SCTP service
+ other than the one defined in this document (i.e., "timed
+ reliability"), then those additional PR-SCTP services should also be
+ specified and standardized in a new RFC.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 17]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ It is suggested that any such additional service definitions be
+ modeled after the contents of Section 4.1. In particular, the
+ service definition should provide:
+
+ 1. A description of how the service user specifies any parameters
+ that need to be associated with a particular message (and/or any
+ other communication that takes place between the application and
+ the SCTP transport sender) that provides the SCTP transport sender
+ with the information needed to determine when to give up on
+ transmission of a particular message.
+
+ Preferably, this description should reference the primitives in
+ the abstract API provided in Section 10 of RFC 2960 [2],
+ indicating any:
+
+ * changes to the interpretation of the existing parameters of
+ existing primitives,
+
+ * additional parameters to be added to existing primitives (these
+ should be OPTIONAL, and default values should be indicated),
+
+ * additional primitives that may be needed.
+
+ 2. A description of the rules used by the sender side implementation
+ to determine when to give up on messages that have not yet been
+ assigned a TSN. This description should also indicate what
+ protocol events trigger the evaluation, and what actions to take
+ (e.g., notifications.)
+
+ 3. A description of the rules used by the sender side implementation
+ to determine when to give up on the transmission or retransmission
+ of messages that have already been assigned a TSN, and may have
+ been transmitted and possibly retransmitted zero or more times.
+
+ Items (2) and (3) in the list above should also indicate what
+ protocol events trigger the evaluation, and what actions to take if
+ the determination is made that the sender should give up on
+ transmitting the message (e.g., notifications to the ULP.)
+
+ Note that in any PR-SCTP service, the following rule MUST be
+ specified to avoid a protocol deadlock:
+
+ (G1) When the sender side implementation gives up on transmitting a
+ message that has been assigned a TSN (i.e., when that message is
+ "abandoned", as defined in Section 3.4), the sender side MUST
+ mark that TSN as eligible for forward TSN, and the rules in
+ Section 3.4 regarding the sending of FORWARD TSN chunks MUST be
+ followed.
+
+
+
+Stewart, et al. Standards Track [Page 18]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ Finally, a PR-SCTP service definition should specify a "canonical
+ service name" to uniquely identify the service, and distinguish it
+ from other PR-SCTP services. This name can then be used in upper
+ layer protocol standards to indicate which PR-SCTP service definition
+ is required by that upper layer protocol. It can also be used in the
+ documentation of APIs of PR-SCTP implementations to indicate how an
+ upper layer indicates which definition of PR-SCTP service should
+ apply. The canonical service name for the PR-SCTP service defined in
+ Section 4.1 is "timed reliability".
+
+4.4. Usage Notes
+
+ Detecting missing data in a PR-SCTP stream is useful for some
+ applications (e.g., Fibre channel or SCSI over IP). With PR-SCTP,
+ this becomes possible - the upper layer simply needs to examine the
+ stream sequence number of the arrived user messages of that stream to
+ detect any missing data. Note, this detection only works when all
+ the messages on that stream are sent in order, i.e., the "U" bit is
+ not set.
+
+5. Variables
+
+ This section defines variables used throughout this document:
+
+ SCTP_LIFETIME_RELIABLE - A user interface indication defined by an
+ implementation and used to indicate when a message is to be
+ considered fully reliable.
+
+6. Acknowledgments
+
+ The authors would like to thank Brian Bidulock, Scott Bradner, Jon
+ Berger, Armando L. Caro Jr., John Loughney, Jon Peterson, Ivan Arias
+ Rodriguez, Ian Rytina, Chip Sharp, and others for their comments.
+
+7. Security Considerations
+
+ This document does not introduce any new security concerns to SCTP
+ other than the ones already documented in RFC 2960 [2]. In
+ particular, this document shares the same security issues as
+ unordered data within RFC 2960 [2] identified by RFC 3436 [4]. An
+ application using the PR-SCTP extension should not use transport
+ layer security; further details can be found in RFC 3436 [4].
+
+ Note that the ability to cause a message to be skipped (i.e, the
+ FORWARD TSN chunk) does not provide any new attack for a Man-In-the-
+ Middle (MIM), since the MIM already is capable of changing and/or
+ withholding data, thus effectively skipping messages. However, the
+ FORWARD TSN chunk does provide a mechanism to make it easier for a
+
+
+
+Stewart, et al. Standards Track [Page 19]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ MIM to skip selective messages when the application has this feature
+ enabled since the MIM would have less state to maintain.
+
+8. IANA Considerations
+
+ IANA has assigned 192 as a new chunk type to SCTP.
+
+ IANA has assigned 49152 as a new parameter type code to SCTP.
+
+9. References
+
+9.1. Normative References
+
+ [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [2] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+9.2. Informative References
+
+ [3] Clark, D. and D. Tennenhouse, "Architectural Considerations for
+ a New Generation of Protocols", SIGCOMM 1990 pp. 200-208,
+ September 1990.
+
+ [4] Jungmaier, A., Rescorla, E. and M. Tuexen, "Transport Layer
+ Security over Stream Control Transmission Protocol", RFC 3436,
+ December 2002.
+
+10. Authors' Addresses
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 8725 West Higgins Road
+ Suite 300
+ Chicago, IL 60631
+ USA
+
+ Phone: +1-815-477-2127
+ EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 20]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+ Michael A. Ramalho
+ Cisco Systems, Inc.
+ 1802 Rue de la Porte
+ Wall Township, NJ 07719-3784
+ USA
+
+ Phone: +1.732.449.5762
+ EMail: mramalho@cisco.com
+
+
+ Qiaobing Xie
+ Motorola, Inc.
+ 1501 W. Shure Drive, #2309
+ Arlington Heights, IL 60004
+ USA
+
+ Phone: +1-847-632-3028
+ EMail: qxie1@email.mot.com
+
+
+ Michael Tuexen
+ Univ. of Applied Sciences Muenster
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Phillip T. Conrad
+ University of Delaware
+ Department of Computer and Information Sciences
+ Newark, DE 19716
+ USA
+
+ Phone: +1 302 831 8622
+ EMail: conrad@acm.org
+ URI: http://www.cis.udel.edu/~pconrad
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 21]
+
+RFC 3758 SCTP Partial Reliability Extension May 2004
+
+
+11. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2004). This document is subject
+ to the rights, licenses and restrictions contained in BCP 78, and
+ except as set forth therein, the authors retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at ietf-
+ ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 22]
+
diff --git a/doc/rfc3873.txt b/doc/rfc3873.txt
new file mode 100644
index 0000000..c583226
--- /dev/null
+++ b/doc/rfc3873.txt
@@ -0,0 +1,2579 @@
+
+
+
+
+
+
+Network Working Group J. Pastor
+Request for Comments: 3873 M. Belinchon
+Category: Standards Track Ericsson
+ September 2004
+
+
+ Stream Control Transmission Protocol (SCTP)
+ Management Information Base (MIB)
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2004).
+
+
+Abstract
+
+ The Stream Control Transmission Protocol (SCTP) is a reliable
+ transport protocol operating on top of a connectionless packet
+ network such as IP. It is designed to transport public switched
+ telephone network (PSTN) signaling messages over the connectionless
+ packet network, but is capable of broader applications.
+
+ This memo defines the Management Information Base (MIB) module which
+ describes the minimum set of objects needed to manage the
+ implementation of the SCTP.
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 1.1. Abbreviations. . . . . . . . . . . . . . . . . . . . . . 2
+ 2. The Internet-Standard Management Framework . . . . . . . . . . 3
+ 3. MIB Structure. . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 3.1. SCTP Objects . . . . . . . . . . . . . . . . . . . . . . 4
+ 3.1.1. SCTP Statistics. . . . . . . . . . . . . . . . . 4
+ 3.1.2. SCTP Parameters. . . . . . . . . . . . . . . . . 5
+ 3.1.3. MIB Tables . . . . . . . . . . . . . . . . . . . 5
+ 3.1.3.1. Association Table. . . . . . . . . . . 5
+ 3.1.3.2. Reverse Lookup Table . . . . . . . . . 8
+ 3.2. Conformance. . . . . . . . . . . . . . . . . . . . . . . 9
+ 4. Definitions. . . . . . . . . . . . . . . . . . . . . . . . . . 9
+
+
+
+Pastor & Belinchon Standards Track [Page 1]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ 5. Compiling Notes. . . . . . . . . . . . . . . . . . . . . . . . 42
+ 6. References . . . . . . . . . . . . . . . . . . . . . . . . . . 42
+ 6.1. Normative References . . . . . . . . . . . . . . . . . . 42
+ 6.2. Informative References . . . . . . . . . . . . . . . . . 43
+ 7. Security Considerations. . . . . . . . . . . . . . . . . . . . 44
+ 8. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 45
+ 9. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 45
+ 10. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 46
+
+1. Introduction
+
+ This memo defines the Management Information Base (MIB) module which
+ describes managed objects for implementations of the SCTP.
+
+ The document starts with a brief description of the SNMP framework
+ and continues with the MIB explanation and security consideration
+ sections among others.
+
+ The managed objects in this MIB module are based on [RFC2012] update:
+ "Management Information Base for the Transmission Control Protocol
+ (TCP)" referred as [TCPMIB] (work in progress), and RFC 3291 "Textual
+ Conventions for Internet Network Addresses" [RFC3291].
+
+ Terms related to the SCTP architecture are explained in [RFC2960].
+ Other specific abbreviations are listed below.
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC2119].
+
+1.1. Abbreviations
+
+ DNS - Domain Name System
+ IANA - Internet Assigned Numbers Authority
+ IETF - Internet Engineering Task Force
+ IP - Internet Protocol
+ MIB - Management Information Base
+ RFC - Request For Comments
+ RTO - Retransmission Time Out
+ SCTP - Stream Control Transmission Protocol
+ SMI - Structure of Management Information
+ SNMP - Simple Network Management Protocol
+ TCB - Transmission Control Block
+ TCP - Transmission Control Protocol
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 2]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+2. The Internet-Standard Management Framework
+
+ For a detailed overview of the documents that describe the current
+ Internet-Standard Management Framework, please refer to section 7 of
+ RFC 3410 [RFC3410].
+
+ Managed objects are accessed via a virtual information store, termed
+ the Management Information Base or MIB. MIB objects are generally
+ accessed through the Simple Network Management Protocol (SNMP).
+ Objects in the MIB are defined using the mechanisms defined in the
+ Structure of Management Information (SMI). This memo specifies a MIB
+ module that is compliant to the SMIv2, which is described in STD 58,
+ RFC 2578 [RFC2578], STD 58, RFC 2579 [RFC2579] and STD 58, RFC 2580
+ [RFC2580].
+
+3. MIB Structure
+
+ This chapter explains the main objects this MIB defines. A detailed
+ view of the MIB structure with the OID values is below.
+
+ MIB-2 {1 3 6 1 2 1}
+ +--(104)sctpMIB
+ |
+ +--(1) sctpObjects
+ | |
+ | +--(1) sctpStats
+ | | |
+ | | +-- <scalars>
+ | |
+ | +--(2)sctpParameters
+ | | |
+ | | +-- <scalars>
+ | |
+ | +--(3) sctpAssocTable
+ | |
+ | +--(4) sctpAssocLocalAddrTable
+ | |
+ | +--(5) sctpAssocRemAddrTable
+ | |
+ | +--(6) sctpLookupLocalPortTable
+ | |
+ | +--(7) sctpLookupRemPortTable
+ | |
+ | +--(8) sctpLookupRemHostNameTable
+ | |
+ | +--(9) sctpLookupRemPrimIPAddrTable
+ | |
+ | +--(10) sctpLookupRemIPAddrTable
+
+
+
+Pastor & Belinchon Standards Track [Page 3]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ |
+ |
+ +--(2)sctpMibConformance
+ |
+ +--(1) sctpMibCompliances
+ | |
+ | +--(1) sctpMibCompliance
+ |
+ +--(2) sctpMibGroups
+ |
+ +--(1) sctpLayerParamsGroup
+ |
+ +--(2) sctpStatsGroup
+ |
+ +--(3) sctpPerAssocParamsGroup
+ |
+ +--(4) sctpInverseGroup
+
+
+ The main groups are explained further in the MIB definition.
+
+3.1. SCTP Objects
+
+ This branch contains the SCTP statistics and general parameters (both
+ of them scalars) and the SCTP MIB tables.
+
+3.1.1. SCTP Statistics
+
+ The SCTP MIB includes both Counter32s and Counter64s to deal with
+ statistics. Counter64s are used for those counters, which are likely
+ to wrap around in less than one hour, according to [RFC2863].
+
+ In addition Gauge32 is also used.
+
+3.1.1.1. State-Related Statistics
+
+ These statistics are based on the TCP model, but adapted to the SCTP
+ states. They store the number of successful association attempts,
+ how many associations have been initiated by the local or the remote
+ SCTP layer, and the number of associations terminated in a graceful
+ (by means of SHUTDOWN procedure) or ungraceful way (by means of CLOSE
+ procedure).
+
+3.1.1.2. Statistics for traffic Measurements
+
+ This set of objects specifies statistics related to the whole SCTP
+ layer. There are, e.g., statistics related to both SCTP packets and
+ SCTP chunks.
+
+
+
+Pastor & Belinchon Standards Track [Page 4]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ Statistics related to a specific association, or local/remote IP
+ addresses are defined inside their associated table.
+
+3.1.2. SCTP Parameters
+
+ This section of the MIB contains the general variables for the SCTP
+ protocol. Maximum, minimum, initial and default values are listed
+ here.
+
+ SCTP RTO mechanism definition is based on the TCP MIB [TCPMIB]. In
+ SCTP, only options 'other' and 'vanj' are valid since SCTP defines
+ Van Jacobson's algorithm (vanj) as the one to be used to calculate
+ RTO. 'Other' is left for future use.
+
+3.1.3. MIB Tables
+
+ There are several tables included in the SCTP MIB. The first group
+ deals with the SCTP association variables and is composed of a main
+ and two extended tables. The second group is a bunch of tables used
+ to perform reverse lookups.
+
+ It is NOT possible to create rows in any table (sctpAssocTable,
+ sctpAssocLocalAddrTable, sctpRemAddrTable and Reverse Lookup tables)
+ using SNMP.
+
+ It is NOT possible to delete rows in any table using SNMP except in
+ sctpAssocTable under the particular conditions explained below.
+
+3.1.3.1. Association Table
+
+ The sctpAssocTable is the main MIB table, where all the association
+ related information is stored on a per association basis. It is
+ structured according to expanded tables. The main table is called
+ sctpAssocTable and is indexed by sctpAssocId (the association
+ identification). This is a value that uniquely identifies an
+ association. The MIB does not restrict what value must be written
+ here, however it must be unique within the table.
+
+ The sctpAssoc index is also shared by two more tables:
+ - sctpAssocLocalAddrTable: to store the local IP address(es).
+ - sctpAssocRemAddrTable: to store the remote addresses and the
+ per-remote-address related information.
+
+ Entries in the sctpAssocTable are created when trying to establish
+ the association, i.e., when sending the COOKIE-ECHO message
+ (originating side) or the COOKIE-ACK message (server side). At this
+ point, i.e., at established state, all entry fields are filled in
+ with valid values.
+
+
+
+Pastor & Belinchon Standards Track [Page 5]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ Note: The following representation is a conceptual mode of describing
+ the relationship between the tables in this MIB. Note that the real
+ relationship of the tables is by sharing an index, so tables are not
+ truly within tables. Every entry is explained when defining the
+ corresponding objects in the MIB.
+
+ mib-2 {1 3 6 1 2 1}
+ +--(104)sctpMIB
+ |
+ +--(1) sctpObjects
+ | |
+ . .
+ . .
+ |
+ +--(3) sctpAssocTable
+ | |
+ | +--(1) sctpAssocId (index)
+ | |
+ | +--(2) sctpAssocRemHostName
+ | |
+ | +--(3) sctpAssocLocalPort
+ | |
+ | +--(4) sctpAssocRemPort
+ | |
+ | +--(5) sctpAssocRemPrimAddrType
+ | |
+ | +--(6) sctpAssocRemPrimAddr
+ | |
+ | +--(7) sctpAssocHeartBeatInterval
+ | |
+ | +--(8) sctpAssocState
+ | |
+ | +--(9) sctpAssocInStreams
+ | |
+ | +--(10) sctpAssocOutStreams
+ | |
+ | +--(11) sctpAssocMaxRetr
+ | |
+ | +--(12) sctpAssocPrimProcess
+ | |
+ | +--(13) sctpAssocT1expireds
+ | |
+ | +--(14) sctpAssocT2expireds
+ | |
+ | +--(15) sctpAssocRtxChunks
+ | |
+ | +--(16) sctpAssocStartTime
+ | |
+
+
+
+Pastor & Belinchon Standards Track [Page 6]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ | +--(17) sctpAssocDiscontinuityTime
+ |
+ |
+ +--(4) sctpAssocLocalAddrTable
+ | |
+ | |--(-) sctpAssocId (shared index)
+ | |
+ | +--(1) sctpAssocLocalAddrType(index)
+ | |
+ | +--(2) sctpAssocLocalAddr (index)
+ | |
+ | +--(3) sctpAssocLocalAddrStartTime
+ |
+ |
+ +--(5) sctpAssocRemAddrTable
+ | |
+ | |--(-) sctpAssocId (shared index)
+ | |
+ | +--(1) sctpAssocRemAddrType (index)
+ . |
+ . +--(2) sctpAssocRemAddr (index)
+ . |
+ +--(3) sctpAssocRemAddrActive
+ |
+ +--(4) sctpAssocRemAddrHBActive
+ |
+ +--(5) sctpAssocRemAddrRTO
+ |
+ +--(6) sctpAssocRemAddrMaxPathRtx
+ |
+ +--(7) sctpAssocRemAddrRtx
+ |
+ +--(8) sctpAssocRemAddrStartTime
+
+ Both sctpAssocLocalAddrTable and sctpAssocRemAddrTable are indexed by
+ addresses. 'Addr' and 'AddrType' use the syntax InetAddress and
+ InetAddressType defined in the Textual Conventions for Internet
+ Network Address (RFC3291). The InetAddressType TC has codepoints for
+ unknown, IPv4, IPv6, non-global IPv4, non-global IPv6, and DNS
+ addresses, but only the IPv4 and IPv6 address types are required to
+ be supported by implementations of this MIB module. Implementations
+ that connect multiple zones are expected to support the non-global
+ IPv4 and non-global IPv6 address types as well.
+
+ Note that DNS addresses are not used in this MIB module. They are
+ always resolved to the on-the-wire form prior to connection setup,
+ and the on-the-wire form is what appears in the MIB objects.
+
+
+
+
+Pastor & Belinchon Standards Track [Page 7]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ The sctpAssocLocalAddrTable table will have as many entries as local
+ IP addresses have been defined for the association. The
+ sctpAssocRemAddrTable table will contain as many entries as remote IP
+ addresses are known to reach the peer. For the multihoming concept
+ see reference RFC2960.
+
+ To keep the name of the remote peer (when provided by the peer at
+ initialization time), an entry has been created in the sctpAssocTable
+ called sctpAssocRemHostName. When no DNS name is provided by the
+ remote endpoint, this value will be NULL (zero-length string).
+ Otherwise, the received DNS name will be stored here.
+
+ If it is necessary to abort an existing association, the value
+ deleteTCB(9) must be written in the variable sctpAssocState. That is
+ the only way to delete rows in any of the mentioned tables.
+
+3.1.3.2. Reverse Lookup Table
+
+ There are five reverse lookup tables to help management applications
+ efficiently access conceptual rows in other tables. These tables
+ allow management applications to avoid expensive tree walks through
+ large numbers of associations.
+
+ All of these tables are optional. If these tables are implemented,
+ an entry in them must be created after the entry in the main table
+ (sctpAssocTable) associated with it has been created. This ensures
+ that the field indexing the lookup table exists.
+
+ The defined reverse lookup tables allow for performing a lookup using
+ the following variables:
+
+ - Local Port: It allows a management application to find all the
+ associations that use a specific local port
+ - Remote Port: It allows a management application to find all the
+ associations that use a specific remote port
+ - Remote Host Name: It allows a management application to find
+ all the associations with a specific host name.
+ - Remote Primary IP Address: It allows a management application
+ to find all the associations that use a specific remote IP
+ address as primary.
+ - Remote IP address: a management application to find all the
+ associations that use a specific remote IP address.
+
+ As an example the picture below shows the table to look up by local
+ port.
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 8]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ MIB-2 {1 3 6 1 2 1}
+ +--(104)sctpMIB
+ |
+ +--(1) sctpObjects
+ | |
+ . .
+ . .
+ | |
+ | +--(6) sctpLookupLocalPortTable
+ | | |
+ . . +--(-) sctpAssocLocalPort (shared index)
+ . . |
+ +--(-) sctpAssocId (shared index)
+ |
+ +--(1) sctpLookupLocalPortStartTime
+
+ It is not possible for the operator to either create or delete rows
+ in these tables. The rows in this table will dynamically appear and
+ be removed as the corresponding entries in sctpAssocTable are.
+
+3.2. Conformance
+
+ The conformance section recommends all the inverse lookup tables in
+ this MIB as optional. General layer and per association parameters
+ and statistics are considered mandatory.
+
+ IP addresses use the global IPv4 and global IPv6 address formats.
+ Unknown value and DNS name formats are not used. Names, if present,
+ are stored in the sctpRemoteHostName variable.
+
+4. Definitions
+
+ SCTP-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32, Gauge32,
+ Counter32, Counter64, mib-2
+ FROM SNMPv2-SMI -- [RFC2578]
+ TimeStamp, TruthValue
+ FROM SNMPv2-TC -- [RFC2579]
+ MODULE-COMPLIANCE, OBJECT-GROUP
+ FROM SNMPv2-CONF -- [RFC2580]
+ InetAddressType, InetAddress, InetPortNumber
+ FROM INET-ADDRESS-MIB; -- [RFC3291]
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 9]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpMIB MODULE-IDENTITY
+ LAST-UPDATED "200409020000Z" -- 2nd September 2004
+ ORGANIZATION "IETF SIGTRAN Working Group"
+ CONTACT-INFO
+ "
+ WG EMail: sigtran@ietf.org
+
+ Web Page:
+ http://www.ietf.org/html.charters/sigtran-charter.html
+
+ Chair: Lyndon Ong
+ Ciena Corporation
+ 0480 Ridgeview Drive
+ Cupertino, CA 95014
+ USA
+ Tel:
+ Email: lyong@ciena.com
+
+ Editors: Maria-Carmen Belinchon
+ R&D Department
+ Ericsson Espana S. A.
+ Via de los Poblados, 13
+ 28033 Madrid
+ Spain
+ Tel: +34 91 339 3535
+ Email: Maria.C.Belinchon@ericsson.com
+
+ Jose-Javier Pastor-Balbas
+ R&D Department
+ Ericsson Espana S. A.
+ Via de los Poblados, 13
+ 28033 Madrid
+ Spain
+ Tel: +34 91 339 1397
+ Email: J.Javier.Pastor@ericsson.com
+ "
+ DESCRIPTION
+ "The MIB module for managing SCTP implementations.
+
+ Copyright (C) The Internet Society (2004). This version of
+ this MIB module is part of RFC 3873; see the RFC itself for
+ full legal notices. "
+
+ REVISION "200409020000Z" -- 2nd September 2004
+
+ DESCRIPTION " Initial version, published as RFC 3873"
+
+ ::= { mib-2 104 }
+
+
+
+Pastor & Belinchon Standards Track [Page 10]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ -- the SCTP base variables group
+
+ sctpObjects OBJECT IDENTIFIER ::= { sctpMIB 1 }
+
+ sctpStats OBJECT IDENTIFIER ::= { sctpObjects 1 }
+ sctpParams OBJECT IDENTIFIER ::= { sctpObjects 2 }
+
+ -- STATISTICS
+ -- **********
+
+ -- STATE-RELATED STATISTICS
+
+ sctpCurrEstab OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of associations for which the current state is
+ either ESTABLISHED, SHUTDOWN-RECEIVED or SHUTDOWN-PENDING."
+ REFERENCE
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpStats 1 }
+
+
+ sctpActiveEstabs OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of times that associations have made a direct
+ transition to the ESTABLISHED state from the COOKIE-ECHOED
+ state: COOKIE-ECHOED -> ESTABLISHED. The upper layer initiated
+ the association attempt."
+ REFERENCE
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpStats 2 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 11]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpPassiveEstabs OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of times that associations have made a direct
+ transition to the ESTABLISHED state from the CLOSED state:
+ CLOSED -> ESTABLISHED. The remote endpoint initiated the
+ association attempt."
+ REFERENCE
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpStats 3 }
+
+
+ sctpAborteds OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of times that associations have made a direct
+ transition to the CLOSED state from any state using the
+ primitive 'ABORT': AnyState --Abort--> CLOSED. Ungraceful
+ termination of the association."
+ REFERENCE
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpStats 4 }
+
+
+ sctpShutdowns OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of times that associations have made a direct
+ transition to the CLOSED state from either the SHUTDOWN-SENT
+ state or the SHUTDOWN-ACK-SENT state. Graceful termination of
+ the association."
+ REFERENCE
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpStats 5 }
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 12]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ -- OTHER LAYER STATISTICS
+
+ sctpOutOfBlues OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of out of the blue packets received by the host.
+ An out of the blue packet is an SCTP packet correctly formed,
+ including the proper checksum, but for which the receiver was
+ unable to identify an appropriate association."
+ REFERENCE
+ "Section 8.4 in RFC2960 deals with the Out-Of-The-Blue
+ (OOTB) packet definition and procedures."
+
+ ::= { sctpStats 6 }
+
+ sctpChecksumErrors OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP packets received with an invalid
+ checksum."
+ REFERENCE
+ "The checksum is located at the end of the SCTP packet as per
+ Section 3.1 in RFC2960. RFC3309 updates SCTP to use a 32 bit
+ CRC checksum."
+
+ ::= { sctpStats 7 }
+
+ sctpOutCtrlChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP control chunks sent (retransmissions are
+ not included). Control chunks are those chunks different from
+ DATA."
+ REFERENCE
+ "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as
+ those chunks different from those that contain user
+ information, i.e., DATA chunks."
+
+ ::= { sctpStats 8 }
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 13]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpOutOrderChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP ordered data chunks sent (retransmissions
+ are not included)."
+ REFERENCE
+ "Section 3.3.1 in RFC2960 defines the ordered data chunk."
+
+ ::= { sctpStats 9 }
+
+ sctpOutUnorderChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP unordered chunks (data chunks in which the
+ U bit is set to 1) sent (retransmissions are not included)."
+ REFERENCE
+ "Section 3.3.1 in RFC2960 defines the unordered data chunk."
+
+ ::= { sctpStats 10 }
+
+ sctpInCtrlChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP control chunks received (no duplicate
+ chunks included)."
+ REFERENCE
+ "Sections 1.3.5 and 1.4 in RFC2960 refer to control chunk as
+ those chunks different from those that contain user
+ information, i.e., DATA chunks."
+
+ ::= { sctpStats 11 }
+
+
+ sctpInOrderChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP ordered data chunks received (no duplicate
+ chunks included)."
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 14]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ REFERENCE
+ "Section 3.3.1 in RFC2960 defines the ordered data chunk."
+
+ ::= { sctpStats 12 }
+
+
+ sctpInUnorderChunks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP unordered chunks (data chunks in which the
+ U bit is set to 1) received (no duplicate chunks included)."
+ REFERENCE
+ "Section 3.3.1 in RFC2960 defines the unordered data chunk."
+
+ ::= { sctpStats 13 }
+
+
+
+ sctpFragUsrMsgs OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+
+ "The number of user messages that have to be fragmented
+ because of the MTU."
+
+ ::= { sctpStats 14 }
+
+
+ sctpReasmUsrMsgs OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of user messages reassembled, after conversion
+ into DATA chunks."
+ REFERENCE
+ "Section 6.9 in RFC2960 includes a description of the
+ reassembly process."
+
+ ::= { sctpStats 15 }
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 15]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpOutSCTPPacks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP packets sent. Retransmitted DATA chunks
+ are included."
+
+ ::= { sctpStats 16 }
+
+
+ sctpInSCTPPacks OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of SCTP packets received. Duplicates are
+ included."
+
+ ::= { sctpStats 17 }
+
+ sctpDiscontinuityTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime on the most recent occasion at which
+ any one or more of this general statistics counters suffered a
+ discontinuity. The relevant counters are the specific
+ instances associated with this interface of any Counter32 or
+ Counter64 object contained in the SCTP layer statistics
+ (defined below sctpStats branch). If no such discontinuities
+ have occurred since the last re-initialization of the local
+ management subsystem, then this object contains a zero value."
+ REFERENCE
+ "The inclusion of this object is recommended by RFC2578."
+
+ ::= { sctpStats 18 }
+
+
+ -- PROTOCOL GENERAL VARIABLES
+ -- **************************
+
+ sctpRtoAlgorithm OBJECT-TYPE
+ SYNTAX INTEGER {
+ other(1), -- Other new one. Future use
+ vanj(2) -- Van Jacobson's algorithm
+ }
+
+
+
+Pastor & Belinchon Standards Track [Page 16]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The algorithm used to determine the timeout value (T3-rtx)
+ used for re-transmitting unacknowledged chunks."
+ REFERENCE
+ "Section 6.3.1 and 6.3.2 in RFC2960 cover the RTO calculation
+ and retransmission timer rules."
+ DEFVAL {vanj} -- vanj(2)
+
+ ::= { sctpParams 1 }
+
+
+ sctpRtoMin OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The minimum value permitted by a SCTP implementation for the
+ retransmission timeout value, measured in milliseconds. More
+ refined semantics for objects of this type depend upon the
+ algorithm used to determine the retransmission timeout value.
+
+ A retransmission time value of zero means immediate
+ retransmission.
+
+ The value of this object has to be lower than or equal to
+ stcpRtoMax's value."
+ DEFVAL {1000} -- milliseconds
+
+ ::= { sctpParams 2 }
+
+ sctpRtoMax OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The maximum value permitted by a SCTP implementation for the
+ retransmission timeout value, measured in milliseconds. More
+ refined semantics for objects of this type depend upon the
+ algorithm used to determine the retransmission timeout value.
+
+ A retransmission time value of zero means immediate re-
+ transmission.
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 17]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ The value of this object has to be greater than or equal to
+ stcpRtoMin's value."
+ DEFVAL {60000} -- milliseconds
+
+ ::= { sctpParams 3 }
+
+
+ sctpRtoInitial OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The initial value for the retransmission timer.
+
+ A retransmission time value of zero means immediate re-
+ transmission."
+ DEFVAL {3000} -- milliseconds
+
+ ::= { sctpParams 4 }
+
+
+ sctpMaxAssocs OBJECT-TYPE
+ SYNTAX Integer32 (-1 | 0..2147483647)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The limit on the total number of associations the entity can
+ support. In entities where the maximum number of associations
+ is dynamic, this object should contain the value -1."
+
+ ::= { sctpParams 5 }
+
+
+ sctpValCookieLife OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Valid cookie life in the 4-way start-up handshake procedure."
+ REFERENCE
+ "Section 5.1.3 in RFC2960 explains the cookie generation
+ process. Recommended value is per section 14 in RFC2960."
+ DEFVAL {60000} -- milliseconds
+
+ ::= { sctpParams 6 }
+
+
+
+Pastor & Belinchon Standards Track [Page 18]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpMaxInitRetr OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The maximum number of retransmissions at the start-up phase
+ (INIT and COOKIE ECHO chunks). "
+ REFERENCE
+ "Section 5.1.4, 5.1.6 in RFC2960 refers to Max.Init.Retransmit
+ parameter. Recommended value is per section 14 in RFC2960."
+ DEFVAL {8} -- number of attempts
+
+ ::= { sctpParams 7 }
+
+
+ -- TABLES
+ -- ******
+
+ -- the SCTP Association TABLE
+
+ -- The SCTP association table contains information about each
+ -- association in which the local endpoint is involved.
+
+
+ sctpAssocTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpAssocEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table containing SCTP association-specific information."
+
+ ::= { sctpObjects 3 }
+
+
+ sctpAssocEntry OBJECT-TYPE
+ SYNTAX SctpAssocEntry
+ MAX-ACCESS not-accessible
+
+ STATUS current
+ DESCRIPTION
+ "General common variables and statistics for the whole
+ association."
+ INDEX { sctpAssocId }
+
+ ::= { sctpAssocTable 1 }
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 19]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ SctpAssocEntry ::= SEQUENCE {
+ sctpAssocId Unsigned32,
+ sctpAssocRemHostName OCTET STRING,
+ sctpAssocLocalPort InetPortNumber,
+ sctpAssocRemPort InetPortNumber,
+ sctpAssocRemPrimAddrType InetAddressType,
+ sctpAssocRemPrimAddr InetAddress,
+ sctpAssocHeartBeatInterval Unsigned32,
+ sctpAssocState INTEGER,
+ sctpAssocInStreams Unsigned32,
+ sctpAssocOutStreams Unsigned32,
+ sctpAssocMaxRetr Unsigned32,
+ sctpAssocPrimProcess Unsigned32,
+ sctpAssocT1expireds Counter32, -- Statistic
+ sctpAssocT2expireds Counter32, -- Statistic
+ sctpAssocRtxChunks Counter32, -- Statistic
+ sctpAssocStartTime TimeStamp,
+ sctpAssocDiscontinuityTime TimeStamp
+ }
+
+
+ sctpAssocId OBJECT-TYPE
+ SYNTAX Unsigned32 (1..4294967295)
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Association Identification. Value identifying the
+ association. "
+
+ ::= { sctpAssocEntry 1 }
+
+
+ sctpAssocRemHostName OBJECT-TYPE
+ SYNTAX OCTET STRING (SIZE(0..255))
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The peer's DNS name. This object needs to have the same
+ format as the encoding in the DNS protocol. This implies that
+ the domain name can be up to 255 octets long, each octet being
+ 0<=x<=255 as value with US-ASCII A-Z having a case insensitive
+ matching.
+
+ If no DNS domain name was received from the peer at init time
+ (embedded in the INIT or INIT-ACK chunk), this object is
+ meaningless. In such cases the object MUST contain a zero-
+ length string value. Otherwise, it contains the remote host
+ name received at init time."
+
+
+
+Pastor & Belinchon Standards Track [Page 20]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ ::= { sctpAssocEntry 2 }
+
+
+ sctpAssocLocalPort OBJECT-TYPE
+ SYNTAX InetPortNumber (1..65535)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The local SCTP port number used for this association."
+
+ ::= { sctpAssocEntry 3 }
+
+
+ sctpAssocRemPort OBJECT-TYPE
+ SYNTAX InetPortNumber (1..65535)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The remote SCTP port number used for this association."
+
+ ::= { sctpAssocEntry 4 }
+
+
+ sctpAssocRemPrimAddrType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The internet type of primary remote IP address. "
+
+ ::= { sctpAssocEntry 5 }
+
+ sctpAssocRemPrimAddr OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The primary remote IP address. The type of this address is
+ determined by the value of sctpAssocRemPrimAddrType.
+
+ The client side will know this value after INIT_ACK message
+ reception, the server side will know this value when sending
+ INIT_ACK message. However, values will be filled in at
+ established(4) state."
+
+ ::= { sctpAssocEntry 6 }
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 21]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpAssocHeartBeatInterval OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The current heartbeat interval..
+
+ Zero value means no HeartBeat, even when the concerned
+ sctpAssocRemAddrHBFlag object is true."
+ DEFVAL {30000} -- milliseconds
+
+ ::= { sctpAssocEntry 7 }
+
+
+ sctpAssocState OBJECT-TYPE
+ SYNTAX INTEGER {
+ closed(1),
+ cookieWait(2),
+ cookieEchoed(3),
+ established(4),
+ shutdownPending(5),
+ shutdownSent(6),
+ shutdownReceived(7),
+ shutdownAckSent(8),
+ deleteTCB(9)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The state of this SCTP association.
+
+ As in TCP, deleteTCB(9) is the only value that may be set by a
+ management station. If any other value is received, then the
+ agent must return a wrongValue error.
+
+ If a management station sets this object to the value
+ deleteTCB(9), then this has the effect of deleting the TCB (as
+ defined in SCTP) of the corresponding association on the
+ managed node, resulting in immediate termination of the
+ association.
+
+ As an implementation-specific option, an ABORT chunk may be
+ sent from the managed node to the other SCTP endpoint as a
+ result of setting the deleteTCB(9) value. The ABORT chunk
+ implies an ungraceful association shutdown."
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 22]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ REFERENCE
+
+ "Section 4 in RFC2960 covers the SCTP Association state
+ diagram."
+
+ ::= { sctpAssocEntry 8 }
+
+
+ sctpAssocInStreams OBJECT-TYPE
+ SYNTAX Unsigned32 (1..65535)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Inbound Streams according to the negotiation at association
+ start up."
+ REFERENCE
+ "Section 1.3 in RFC2960 includes a definition of stream.
+ Section 5.1.1 in RFC2960 covers the streams negotiation
+ process."
+
+ ::= { sctpAssocEntry 9 }
+
+ sctpAssocOutStreams OBJECT-TYPE
+ SYNTAX Unsigned32 (1..65535)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outbound Streams according to the negotiation at association
+ start up. "
+ REFERENCE
+ "Section 1.3 in RFC2960 includes a definition of stream.
+ Section 5.1.1 in RFC2960 covers the streams negotiation
+ process."
+
+ ::= { sctpAssocEntry 10 }
+
+
+ sctpAssocMaxRetr OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The maximum number of data retransmissions in the association
+ context. This value is specific for each association and the
+ upper layer can change it by calling the appropriate
+ primitives. This value has to be smaller than the addition of
+ all the maximum number for all the paths
+ (sctpAssocRemAddrMaxPathRtx).
+
+
+
+Pastor & Belinchon Standards Track [Page 23]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ A value of zero value means no retransmissions."
+ DEFVAL {10} -- number of attempts
+
+ ::= { sctpAssocEntry 11 }
+
+ sctpAssocPrimProcess OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "This object identifies the system level process which holds
+ primary responsibility for the SCTP association.
+ Wherever possible, this should be the system's native unique
+ identification number. The special value 0 can be used to
+ indicate that no primary process is known.
+
+ Note that the value of this object can be used as a pointer
+ into the swRunTable of the HOST-RESOURCES-MIB(if the value is
+ smaller than 2147483647) or into the sysApplElmtRunTable of
+ the SYSAPPL-MIB."
+
+ ::= { sctpAssocEntry 12 }
+
+
+ -- Association Statistics
+
+ sctpAssocT1expireds OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The T1 timer determines how long to wait for an
+ acknowledgement after sending an INIT or COOKIE-ECHO chunk.
+ This object reflects the number of times the T1 timer expires
+ without having received the acknowledgement.
+
+ Discontinuities in the value of this counter can occur at re-
+ initialization of the management system, and at other times as
+ indicated by the value of sctpAssocDiscontinuityTime."
+ REFERENCE
+ "Section 5 in RFC2960."
+
+
+ ::= { sctpAssocEntry 13 }
+
+ sctpAssocT2expireds OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+
+
+
+Pastor & Belinchon Standards Track [Page 24]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ STATUS current
+ DESCRIPTION
+ "The T2 timer determines how long to wait for an
+ acknowledgement after sending a SHUTDOWN or SHUTDOWN-ACK
+ chunk. This object reflects the number of times that T2- timer
+ expired.
+
+ Discontinuities in the value of this counter can occur at re-
+ initialization of the management system, and at other times as
+ indicated by the value of sctpAssocDiscontinuityTime."
+ REFERENCE
+ "Section 9.2 in RFC2960."
+ ::= { sctpAssocEntry 14 }
+
+
+ sctpAssocRtxChunks OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "When T3-rtx expires, the DATA chunks that triggered the T3
+ timer will be re-sent according with the retransmissions
+ rules. Every DATA chunk that was included in the SCTP packet
+ that triggered the T3-rtx timer must be added to the value of
+ this counter.
+
+ Discontinuities in the value of this counter can occur at re-
+ initialization of the management system, and at other times as
+ indicated by the value of sctpAssocDiscontinuityTime."
+ REFERENCE
+ "Section 6 in RFC2960 covers the retransmission process and
+ rules."
+
+ ::= { sctpAssocEntry 15 }
+
+
+ sctpAssocStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that the association
+ represented by this row enters the ESTABLISHED state, i.e.,
+ the sctpAssocState object is set to established(4). The
+ value of this object will be zero:
+ - before the association enters the established(4)
+ state, or
+
+
+
+
+Pastor & Belinchon Standards Track [Page 25]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ - if the established(4) state was entered prior to
+ the last re-initialization of the local network management
+ subsystem."
+
+ ::= { sctpAssocEntry 16 }
+
+ sctpAssocDiscontinuityTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime on the most recent occasion at which
+ any one or more of this SCTP association counters suffered a
+ discontinuity. The relevant counters are the specific
+ instances associated with this interface of any Counter32 or
+ Counter64 object contained in the sctpAssocTable or
+ sctpLocalAddrTable or sctpRemAddrTable. If no such
+ discontinuities have occurred since the last re-initialization
+ of the local management subsystem, then this object contains a
+ zero value. "
+ REFERENCE
+ "The inclusion of this object is recommended by RFC2578."
+
+ ::= { sctpAssocEntry 17 }
+
+ -- Expanded tables: Including Multi-home feature
+
+ -- Local Address TABLE
+ -- *******************
+
+ sctpAssocLocalAddrTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpAssocLocalAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Expanded table of sctpAssocTable based on the AssocId index.
+ This table shows data related to each local IP address which
+ is used by this association."
+
+ ::= { sctpObjects 4 }
+
+ sctpAssocLocalAddrEntry OBJECT-TYPE
+ SYNTAX SctpAssocLocalAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Local information about the available addresses. There will
+ be an entry for every local IP address defined for this
+
+
+
+Pastor & Belinchon Standards Track [Page 26]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ association.
+ Implementors need to be aware that if the size of
+ sctpAssocLocalAddr exceeds 114 octets then OIDs of column
+ instances in this table will have more than 128 sub-
+ identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+ SNMPv3."
+ INDEX { sctpAssocId, -- shared index
+ sctpAssocLocalAddrType,
+ sctpAssocLocalAddr }
+
+ ::= { sctpAssocLocalAddrTable 1 }
+
+
+ SctpAssocLocalAddrEntry ::= SEQUENCE {
+ sctpAssocLocalAddrType InetAddressType,
+ sctpAssocLocalAddr InetAddress,
+ sctpAssocLocalAddrStartTime TimeStamp
+ }
+
+
+ sctpAssocLocalAddrType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Internet type of local IP address used for this association."
+
+
+ ::= { sctpAssocLocalAddrEntry 1 }
+
+ sctpAssocLocalAddr OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The value of a local IP address available for this
+ association. The type of this address is determined by the
+ value of sctpAssocLocalAddrType."
+
+ ::= { sctpAssocLocalAddrEntry 2 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 27]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpAssocLocalAddrStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that this row was
+ created."
+
+ ::= { sctpAssocLocalAddrEntry 3 }
+
+ -- Remote Addresses TABLE
+ -- **********************
+
+ sctpAssocRemAddrTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpAssocRemAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Expanded table of sctpAssocTable based on the AssocId index.
+ This table shows data related to each remote peer IP address
+ which is used by this association."
+
+ ::= { sctpObjects 5 }
+
+
+ sctpAssocRemAddrEntry OBJECT-TYPE
+ SYNTAX SctpAssocRemAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Information about the most important variables for every
+ remote IP address. There will be an entry for every remote IP
+ address defined for this association.
+
+ Implementors need to be aware that if the size of
+ sctpAssocRemAddr exceeds 114 octets then OIDs of column
+ instances in this table will have more than 128 sub-
+ identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+ SNMPv3."
+ INDEX { sctpAssocId, -- shared index
+ sctpAssocRemAddrType,
+ sctpAssocRemAddr }
+
+ ::= { sctpAssocRemAddrTable 1 }
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 28]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ SctpAssocRemAddrEntry ::= SEQUENCE {
+ sctpAssocRemAddrType InetAddressType,
+ sctpAssocRemAddr InetAddress,
+ sctpAssocRemAddrActive TruthValue,
+ sctpAssocRemAddrHBActive TruthValue,
+ sctpAssocRemAddrRTO Unsigned32,
+ sctpAssocRemAddrMaxPathRtx Unsigned32,
+ sctpAssocRemAddrRtx Counter32, -- Statistic
+ sctpAssocRemAddrStartTime TimeStamp
+ }
+
+
+ sctpAssocRemAddrType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Internet type of a remote IP address available for this
+ association."
+ ::= { sctpAssocRemAddrEntry 1 }
+
+
+ sctpAssocRemAddr OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The value of a remote IP address available for this
+ association. The type of this address is determined by the
+ value of sctpAssocLocalAddrType."
+
+ ::= { sctpAssocRemAddrEntry 2 }
+
+
+ sctpAssocRemAddrActive OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "This object gives information about the reachability of this
+ specific remote IP address.
+
+ When the object is set to 'true' (1), the remote IP address is
+ understood as Active. Active means that the threshold of no
+ answers received from this IP address has not been reached.
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 29]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ When the object is set to 'false' (2), the remote IP address
+ is understood as Inactive. Inactive means that either no
+ heartbeat or any other message was received from this address,
+ reaching the threshold defined by the protocol."
+
+ REFERENCE
+ "The remote transport states are defined as Active and
+ Inactive in the SCTP, RFC2960."
+
+ ::= { sctpAssocRemAddrEntry 3 }
+
+
+ sctpAssocRemAddrHBActive OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "This object indicates whether the optional Heartbeat check
+ associated to one destination transport address is activated
+ or not (value equal to true or false, respectively). "
+
+ ::= { sctpAssocRemAddrEntry 4 }
+
+
+ sctpAssocRemAddrRTO OBJECT-TYPE -- T3-rtx- Timer
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The current Retransmission Timeout. T3-rtx timer as defined
+ in the protocol SCTP."
+ REFERENCE
+ "Section 6.3 in RFC2960 deals with the Retransmission Timer
+ Management."
+
+ ::= { sctpAssocRemAddrEntry 5 }
+
+
+ sctpAssocRemAddrMaxPathRtx OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Maximum number of DATA chunks retransmissions allowed to a
+ remote IP address before it is considered inactive, as defined
+ in RFC2960."
+
+
+
+
+Pastor & Belinchon Standards Track [Page 30]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ REFERENCE
+ "Section 8.2, 8.3 and 14 in RFC2960."
+ DEFVAL {5} -- number of attempts
+
+ ::= { sctpAssocRemAddrEntry 6 }
+
+
+ -- Remote Address Statistic
+
+ sctpAssocRemAddrRtx OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of DATA chunks retransmissions to this specific IP
+ address. When T3-rtx expires, the DATA chunk that triggered
+ the T3 timer will be re-sent according to the retransmissions
+ rules. Every DATA chunk that is included in a SCTP packet and
+ was transmitted to this specific IP address before, will be
+ included in this counter.
+
+ Discontinuities in the value of this counter can occur at re-
+ initialization of the management system, and at other times as
+ indicated by the value of sctpAssocDiscontinuityTime."
+
+ ::= { sctpAssocRemAddrEntry 7 }
+
+ sctpAssocRemAddrStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that this row was
+ created."
+
+ ::= { sctpAssocRemAddrEntry 8 }
+
+ -- ASSOCIATION INVERSE TABLE
+ -- *************************
+
+ -- BY LOCAL PORT
+
+ sctpLookupLocalPortTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpLookupLocalPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "With the use of this table, a list of associations which are
+
+
+
+Pastor & Belinchon Standards Track [Page 31]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ using the specified local port can be retrieved."
+
+ ::= { sctpObjects 6 }
+
+
+ sctpLookupLocalPortEntry OBJECT-TYPE
+ SYNTAX SctpLookupLocalPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table is indexed by local port and association ID.
+ Specifying a local port, we would get a list of the
+ associations whose local port is the one specified."
+
+ INDEX { sctpAssocLocalPort,
+ sctpAssocId }
+
+ ::= { sctpLookupLocalPortTable 1 }
+
+
+ SctpLookupLocalPortEntry::= SEQUENCE {
+ sctpLookupLocalPortStartTime TimeStamp
+ }
+
+
+ sctpLookupLocalPortStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that this row was created.
+
+ As the table will be created after the sctpAssocTable
+ creation, this value could be equal to the sctpAssocStartTime
+ object from the main table."
+
+ ::= { sctpLookupLocalPortEntry 1 }
+
+ -- BY REMOTE PORT
+
+ sctpLookupRemPortTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpLookupRemPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 32]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ DESCRIPTION
+ "With the use of this table, a list of associations which are
+ using the specified remote port can be got"
+
+ ::= { sctpObjects 7 }
+
+ sctpLookupRemPortEntry OBJECT-TYPE
+ SYNTAX SctpLookupRemPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table is indexed by remote port and association ID.
+ Specifying a remote port we would get a list of the
+ associations whose local port is the one specified "
+
+ INDEX { sctpAssocRemPort,
+ sctpAssocId }
+
+ ::= { sctpLookupRemPortTable 1 }
+
+ SctpLookupRemPortEntry::= SEQUENCE {
+ sctpLookupRemPortStartTime TimeStamp
+ }
+
+
+ sctpLookupRemPortStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that this row was created.
+
+ As the table will be created after the sctpAssocTable
+ creation, this value could be equal to the sctpAssocStartTime
+ object from the main table."
+
+ ::= { sctpLookupRemPortEntry 1 }
+
+ -- BY REMOTE HOST NAME
+
+ sctpLookupRemHostNameTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpLookupRemHostNameEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "With the use of this table, a list of associations with that
+ particular host can be retrieved."
+
+
+
+
+Pastor & Belinchon Standards Track [Page 33]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ ::= { sctpObjects 8 }
+
+
+ sctpLookupRemHostNameEntry OBJECT-TYPE
+ SYNTAX SctpLookupRemHostNameEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table is indexed by remote host name and association ID.
+ Specifying a host name we would get a list of the associations
+ specifying that host name as the remote one.
+
+ Implementors need to be aware that if the size of
+ sctpAssocRemHostName exceeds 115 octets then OIDs of column
+ instances in this table will have more than 128 sub-
+ identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+ SNMPv3."
+
+ INDEX { sctpAssocRemHostName,
+ sctpAssocId }
+
+ ::= { sctpLookupRemHostNameTable 1 }
+
+
+ SctpLookupRemHostNameEntry::= SEQUENCE {
+ sctpLookupRemHostNameStartTime TimeStamp
+ }
+
+ sctpLookupRemHostNameStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of sysUpTime at the time that this row was created.
+
+ As the table will be created after the sctpAssocTable
+ creation, this value could be equal to the sctpAssocStartTime
+ object from the main table."
+
+ ::= { sctpLookupRemHostNameEntry 1 }
+
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 34]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ -- BY REMOTE PRIMARY IP ADDRESS
+
+ sctpLookupRemPrimIPAddrTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpLookupRemPrimIPAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "With the use of this table, a list of associations that have
+ the specified IP address as primary within the remote set of
+ active addresses can be retrieved."
+
+ ::= { sctpObjects 9 }
+
+
+ sctpLookupRemPrimIPAddrEntry OBJECT-TYPE
+ SYNTAX SctpLookupRemPrimIPAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table is indexed by primary address and association ID.
+ Specifying a primary address, we would get a list of the
+ associations that have the specified remote IP address marked
+ as primary.
+ Implementors need to be aware that if the size of
+ sctpAssocRemPrimAddr exceeds 114 octets then OIDs of column
+ instances in this table will have more than 128 sub-
+ identifiers and cannot be accessed using SNMPv1, SNMPv2c, or
+ SNMPv3."
+
+ INDEX { sctpAssocRemPrimAddrType,
+ sctpAssocRemPrimAddr,
+ sctpAssocId }
+
+ ::= { sctpLookupRemPrimIPAddrTable 1 }
+
+ SctpLookupRemPrimIPAddrEntry::= SEQUENCE {
+ sctpLookupRemPrimIPAddrStartTime TimeStamp
+ }
+
+
+ sctpLookupRemPrimIPAddrStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 35]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ DESCRIPTION
+ "The value of SysUpTime at the time that this row was created.
+
+ As the table will be created after the sctpAssocTable
+ creation, this value could be equal to the sctpAssocStartTime
+ object from the main table."
+
+ ::= { sctpLookupRemPrimIPAddrEntry 1 }
+
+
+ -- BY REMOTE IP ADDRESS
+
+ sctpLookupRemIPAddrTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SctpLookupRemIPAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "With the use of this table, a list of associations that have
+ the specified IP address as one of the remote ones can be
+ retrieved. "
+
+ ::= { sctpObjects 10 }
+
+
+ sctpLookupRemIPAddrEntry OBJECT-TYPE
+ SYNTAX SctpLookupRemIPAddrEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table is indexed by a remote IP address and association
+ ID. Specifying an IP address we would get a list of the
+ associations that have the specified IP address included
+ within the set of remote IP addresses."
+
+ INDEX { sctpAssocRemAddrType,
+ sctpAssocRemAddr,
+ sctpAssocId }
+
+ ::= { sctpLookupRemIPAddrTable 1 }
+
+
+ SctpLookupRemIPAddrEntry::= SEQUENCE {
+
+ sctpLookupRemIPAddrStartTime TimeStamp
+ }
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 36]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpLookupRemIPAddrStartTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of SysUpTime at the time that this row was created.
+
+ As the table will be created after the sctpAssocTable
+ creation, this value could be equal to the sctpAssocStartTime
+ object from the main table."
+
+ ::= { sctpLookupRemIPAddrEntry 1 }
+
+
+ -- 4.1 Conformance Information
+
+ sctpMibConformance OBJECT IDENTIFIER ::= { sctpMIB 2 }
+ sctpMibCompliances OBJECT IDENTIFIER ::= { sctpMibConformance 1 }
+ sctpMibGroups OBJECT IDENTIFIER ::= { sctpMibConformance 2 }
+
+
+ -- 4.1.1 Units of conformance
+
+ --
+ -- MODULE GROUPS
+ --
+
+ sctpLayerParamsGroup OBJECT-GROUP
+ OBJECTS { sctpRtoAlgorithm,
+ sctpRtoMin,
+ sctpRtoMax,
+ sctpRtoInitial,
+ sctpMaxAssocs,
+ sctpValCookieLife,
+ sctpMaxInitRetr
+ }
+
+ STATUS current
+ DESCRIPTION
+ "Common parameters for the SCTP layer, i.e., for all the
+ associations. They can usually be referred to as configuration
+ parameters."
+
+ ::= { sctpMibGroups 1 }
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 37]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpStatsGroup OBJECT-GROUP
+ OBJECTS { sctpCurrEstab,
+ sctpActiveEstabs,
+ sctpPassiveEstabs,
+ sctpAborteds,
+ sctpShutdowns,
+ sctpOutOfBlues,
+ sctpChecksumErrors,
+ sctpOutCtrlChunks,
+ sctpOutOrderChunks,
+ sctpOutUnorderChunks,
+ sctpInCtrlChunks,
+ sctpInOrderChunks,
+ sctpInUnorderChunks,
+ sctpFragUsrMsgs,
+ sctpReasmUsrMsgs,
+ sctpOutSCTPPacks,
+ sctpInSCTPPacks,
+ sctpDiscontinuityTime,
+ sctpAssocT1expireds,
+ sctpAssocT2expireds,
+ sctpAssocRtxChunks,
+ sctpAssocRemAddrRtx
+ }
+
+ STATUS current
+ DESCRIPTION
+ "Statistics group. It includes the objects to collect state
+ changes in the SCTP protocol local layer and flow control
+ statistics."
+
+ ::= { sctpMibGroups 2 }
+
+
+ sctpPerAssocParamsGroup OBJECT-GROUP
+ OBJECTS { sctpAssocRemHostName,
+ sctpAssocLocalPort,
+ sctpAssocRemPort,
+ sctpAssocRemPrimAddrType,
+ sctpAssocRemPrimAddr,
+ sctpAssocHeartBeatInterval,
+ sctpAssocState,
+ sctpAssocInStreams,
+ sctpAssocOutStreams,
+ sctpAssocMaxRetr,
+ sctpAssocPrimProcess,
+ sctpAssocStartTime,
+ sctpAssocDiscontinuityTime,
+
+
+
+Pastor & Belinchon Standards Track [Page 38]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ sctpAssocLocalAddrStartTime,
+ sctpAssocRemAddrActive,
+ sctpAssocRemAddrHBActive,
+ sctpAssocRemAddrRTO,
+ sctpAssocRemAddrMaxPathRtx,
+ sctpAssocRemAddrStartTime
+ }
+
+ STATUS current
+ DESCRIPTION
+ "The SCTP group of objects to manage per-association
+ parameters. These variables include all the SCTP basic
+ features."
+
+ ::= { sctpMibGroups 3 }
+
+ sctpPerAssocStatsGroup OBJECT-GROUP
+ OBJECTS
+ { sctpAssocT1expireds,
+ sctpAssocT2expireds,
+ sctpAssocRtxChunks,
+ sctpAssocRemAddrRtx
+ }
+
+ STATUS current
+ DESCRIPTION
+ "Per Association Statistics group. It includes the objects to
+ collect flow control statistics per association."
+
+ ::= { sctpMibGroups 4 }
+
+ sctpInverseGroup OBJECT-GROUP
+ OBJECTS { sctpLookupLocalPortStartTime,
+ sctpLookupRemPortStartTime,
+ sctpLookupRemHostNameStartTime,
+ sctpLookupRemPrimIPAddrStartTime,
+ sctpLookupRemIPAddrStartTime
+ }
+
+ STATUS current
+ DESCRIPTION
+ "Objects used in the inverse lookup tables."
+
+ ::= { sctpMibGroups 5 }
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 39]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ -- 4.1.2 Compliance Statements
+
+ --
+ -- MODULE COMPLIANCES
+ --
+
+ sctpMibCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION
+ "The compliance statement for SNMP entities which implement
+ this SCTP MIB Module.
+
+ There are a number of INDEX objects that cannot be represented
+ in the form of OBJECT clauses in SMIv2, but for which we have
+ the following compliance requirements, expressed in OBJECT
+ clause form in this description clause:
+
+ -- OBJECT sctpAssocLocalAddrType
+ -- SYNTAX InetAddressType {ipv4(1), ipv6(2)}
+ -- DESCRIPTION
+ -- It is only required to have IPv4 and IPv6 addresses without
+ -- zone indices.
+ -- The address with zone indices is required if an
+ -- implementation can connect multiple zones.
+ --
+ -- OBJECT sctpAssocLocalAddr
+ -- SYNTAX InetAddress (SIZE(4|16))
+ -- DESCRIPTION
+ -- An implementation is only required to support globally
+ -- unique IPv4 and IPv6 addresses.
+ --
+ -- OBJECT sctpAssocRemAddrType
+ -- SYNTAX InetAddressType {ipv4(1), ipv6(2)}
+ -- DESCRIPTION
+ -- It is only required to have IPv4 and IPv6 addresses without
+ -- zone indices.
+ -- The address with zone indices is required if an
+ -- implementation can connect multiple zones.
+ --
+ -- OBJECT sctpAssocRemAddr
+ -- SYNTAX InetAddress (SIZE(4|16))
+ -- DESCRIPTION
+ -- An implementation is only required to support globally
+ -- unique IPv4 and IPv6 addresses.
+ --
+ " -- closes DESCRIPTION clause of MODULE-COMPLIANCE
+
+ MODULE -- this module
+
+
+
+Pastor & Belinchon Standards Track [Page 40]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ MANDATORY-GROUPS { sctpLayerParamsGroup,
+ sctpPerAssocParamsGroup,
+ sctpStatsGroup,
+ sctpPerAssocStatsGroup
+ }
+
+ OBJECT sctpAssocRemPrimAddrType
+ SYNTAX InetAddressType { ipv4(1),
+ ipv6(2)
+ }
+ DESCRIPTION
+ "It is only required to have IPv4 and IPv6 addresses
+ without zone indices.
+
+ The address with zone indices is required if an
+ implementation can connect multiple zones."
+
+ OBJECT sctpAssocRemPrimAddr
+ SYNTAX InetAddress (SIZE(4|16))
+ DESCRIPTION
+ "An implementation is only required to support globally
+ unique IPv4 and globally unique IPv6 addresses."
+
+
+ OBJECT sctpAssocState
+ WRITE-SYNTAX INTEGER { deleteTCB(9) }
+ MIN-ACCESS read-only
+ DESCRIPTION
+ "Only the deleteTCB(9) value MAY be set by a management
+ station at most. A read-only option is also considered to
+ be compliant with this MIB module description."
+
+ GROUP sctpInverseGroup
+ DESCRIPTION
+ "Objects used in inverse lookup tables. This should be
+ implemented, at the discretion of the implementers, for
+ easier lookups in the association tables"
+
+ ::= { sctpMibCompliances 1 }
+
+ END
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 41]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+5. Compiling Notes
+
+ When compiling the MIB module warnings similar to the following may
+ occur:
+
+ - warning: index of row `sctpAssocLocalAddrEntry' can exceed OID
+ size limit by 141 subidentifier(s)
+ - warning: index of row `sctpAssocRemAddrEntry' can exceed OID
+ size limit by 141 subidentifier(s)
+ - warning: index of row `sctpLookupRemHostNameEntry' can exceed
+ OID size limit by 140 subidentifier(s)
+ - warning: index of row `sctpLookupRemPrimIPAddrEntry' can exceed
+ OID size limit by 141 subidentifier(s)
+ - warning: index of row `sctpLookupRemIPAddrEntry' can exceed OID
+ size limit by 141 subidentifier(s)
+
+ These warnings are due to the fact that the row objects have index
+ objects of type InetAddress or OCTET STRING whose size limit is 255
+ octets, and if that size limit were reached the names of column
+ instances in those rows would exceed the 128 sub-identifier limit
+ imposed by current versions of the SNMP. Actual limitations for the
+ index object sizes are noted in the conceptual row DESCRIPTION
+ clauses. For the InetAddress index objects these size limits will
+ not be reached with any of the address types in current use.
+
+6. References
+
+6.1. Normative References
+
+ [RFC2578] McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+ "Structure of Management Information Version 2 (SMIv2)",
+ STD 58, RFC 2578, April 1999.
+
+ [RFC2579] McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+ "Textual Conventions for SMIv2", STD 58, RFC 2579, April
+ 1999.
+
+ [RFC2580] McCloghrie, K., Perkins, D., and J. Schoenwaelder,
+ "Conformance Statements for SMIv2", STD 58, RFC 2580,
+ April 1999.
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L., and V. Paxson, "Stream Control Transmission
+ Protocol", RFC 2960, October 2000.
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 42]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ [RFC3291] Daniele, M., Haberman, B., Routhier, S., and J.
+ Schoenwaelder, "Textual Conventions for Internet Network
+ Addresses", RFC 3291, May 2002.
+
+ [RFC3309] Stone, J., Stewart, R., and D. Otis, "Stream Control
+ Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+ September 2002.
+
+6.2. Informative References
+
+ [RFC1213] McCloghrie, K. and M. Rose, "Management Information Base
+ for Network Management of TCP/IP-based internets:MIB-
+ II", STD 17, RFC 1213, March 1991.
+
+ [RFC2012] McCloghrie, K., "SNMPv2 Management Information Base for
+ the Transmission Control Protocol using SMIv2", RFC
+ 2012, November 1996.
+
+ [RFC3410] Case, J., Mundy, R., Partain, D., and B. Stewart,
+ "Introduction and Applicability Statements for
+ Internet-Standard Management Framework", RFC 3410,
+ December 2002.
+
+ [VANJ] Jacobson, V., "Congestion Avoidance and Control",
+ SIGCOMM 1988, Stanford, California.
+
+ [IPv6ARCH] Deering, S., Haberman, B., Jinmei, T., Nordmark, E.,
+ Onoe, A., and B. Zill, "IPv6 Scoped Address
+ Architecture", Work in Progress, December 2002.
+
+ [sctpImplem] Stewart, R., Ong, L., Arias-Rodriguez, I., Caro, A., and
+ M. Tuexen, "Stream Control Transmission Protocol (SCTP)
+ Implementers Guide", Work in Progress, January 2002.
+
+ [TCPMIB] Fenner, B., McCloghrie, K., Raghunarayan, R., and J.
+ Schoenwalder, "Management Information Base for the
+ Transmission Control Protocol (TCP)", Work in Progress,
+ November 2002.
+
+ [UDPMIB] Fenner, B., "Management Information Base for User
+ Datagram Protocol (UDP)", Work in Progress, June 2002.
+
+ [MIBGUIDE] Heard, C.M., "Guidelines for MIB Authors and Reviewers",
+ Work in Progress, February 2003.
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 43]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+7. Security Considerations
+
+ There are management objects defined in this MIB that have a MAX-
+ ACCESS clause of read-write and/or read-create. Such objects may be
+ considered sensitive or vulnerable in some network environments. The
+ support for SET operations in a non-secure environment without proper
+ protection can have a negative effect on network operations. These
+ are the tables and objects and their sensitivity/vulnerability:
+
+ o The sctpAssocState object has a MAX-ACCESS clause of read-write,
+ which allows termination of an arbitrary connection. Unauthorized
+ access could cause a denial of service.
+
+ Some of the readable objects in this MIB module (i.e., objects with a
+ MAX-ACCESS other than not-accessible) may be considered sensitive or
+ vulnerable in some network environments. Thus, it is important to
+ control even GET and/or NOTIFY access to these objects and possibly
+ to even encrypt the values of these objects when sending them over
+ the network via SNMP. These are the tables and objects and their
+ sensitivity/vulnerability:
+
+ o The sctpAssocTable, sctpAssocLocalAddressTable,
+ sctpAssocRemAddressTable and the lookup tables contain objects
+ providing information on the active associations on the device,
+ local and peer's IP addresses, the status of these associations
+ and the associated processes. This information may be used by an
+ attacker to launch attacks against known/unknown weakness in
+ certain protocols/applications.
+
+ o The sctpAssocTable contains objects providing information on local
+ and remote ports objects, that can be used to identify what ports
+ are open on the machine and can thus suggest what attacks are
+ likely to succeed, without the attacker having to run a port
+ scanner.
+
+ SNMP versions prior to SNMPv3 did not include adequate security.
+ Even if the network itself is secure (for example by using IPSec),
+ even then, there is no control as to who on the secure network is
+ allowed to access and GET/SET (read/change/create/delete) the objects
+ in this MIB module.
+
+ It is RECOMMENDED that implementers consider the security features as
+ provided by the SNMPv3 framework (see [RFC3410], section 8),
+ including full support for the SNMPv3 cryptographic mechanisms (for
+ authentication and privacy).
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 44]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+ Further, deployment of SNMP versions prior to SNMPv3 is NOT
+ RECOMMENDED. Instead, it is RECOMMENDED to deploy SNMPv3 and to
+ enable cryptographic security. It is then a customer/operator
+ responsibility to ensure that the SNMP entity giving access to an
+ instance of this MIB module is properly configured to give access to
+ the objects only to those principals (users) that have legitimate
+ rights to indeed GET or SET (change/create/delete) them.
+
+ The above objects also have privacy implications, i.e., they disclose
+ who is connecting to what hosts. These are sensitive from a
+ perspective of preventing traffic analysis, and also to protect
+ individual privacy.
+
+8. Acknowledgments
+
+ The authors wish to thank Juergen Schoenwaelder, David Partain, Shawn
+ A. Routhier, Ed Yarwood, John Linton, Shyamal Prasad, Juan-Francisco
+ Martin, Dave Thaler, and Bert Wijnen for their invaluable comments.
+
+9. Authors' Addresses
+
+ Javier Pastor-Balbas
+ Ericsson Espana S.A.
+ Network Signaling System Management
+ Via de los Poblados 13
+ Madrid, 28033
+ Spain
+
+ Phone: +34-91-339-1397
+ EMail: J.Javier.Pastor@ericsson.com
+
+
+ Maria-Carmen Belinchon
+ Ericsson Espana S.A.
+ Network Signaling System Management
+ Via de los Poblados 13
+ Madrid, 28033
+ Spain
+
+ Phone: +34-91-339-3535
+ EMail: maria.carmen.belinchon@ericsson.com
+
+
+
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 45]
+
+RFC 3873 SCTP MIB using SMIv2 September 2004
+
+
+10. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2004).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE
+ REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
+ INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the IETF's procedures with respect to rights in IETF Documents can
+ be found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at ietf-
+ ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+Pastor & Belinchon Standards Track [Page 46]
+
diff --git a/doc/rfc4460.txt b/doc/rfc4460.txt
new file mode 100644
index 0000000..1345b19
--- /dev/null
+++ b/doc/rfc4460.txt
@@ -0,0 +1,6107 @@
+
+
+
+
+
+
+Network Working Group R. Stewart
+Request for Comments: 4460 Cisco Systems, Inc.
+Category: Informational I. Arias-Rodriguez
+ Nokia Research Center
+ K. Poon
+ Sun Microsystems, Inc.
+ A. Caro
+ BBN Technologies
+ M. Tuexen
+ Muenster Univ. of Applied Sciences
+ April 2006
+
+
+ Stream Control Transmission Protocol (SCTP) Specification
+ Errata and Issues
+
+
+Status of This Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+Abstract
+
+ This document is a compilation of issues found during six
+ interoperability events and 5 years of experience with implementing,
+ testing, and using Stream Control Transmission Protocol (SCTP) along
+ with the suggested fixes. This document provides deltas to RFC 2960
+ and is organized in a time-based way. The issues are listed in the
+ order they were brought up. Because some text is changed several
+ times, the last delta in the text is the one that should be applied.
+ In addition to the delta, a description of the problem and the
+ details of the solution are also provided.
+
+Table of Contents
+
+ 1. Introduction ....................................................6
+ 1.1. Conventions ................................................7
+ 2. Corrections to RFC 2960 .........................................7
+ 2.1. Incorrect Error Type During Chunk Processing. ..............7
+ 2.1.1. Description of the Problem ..........................7
+ 2.1.2. Text changes to the document ........................7
+ 2.1.3. Solution Description ................................7
+
+
+
+Stewart, et al. Informational [Page 1]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 2.2. Parameter Processing Issue .................................7
+ 2.2.1. Description of the Problem ..........................7
+ 2.2.2. Text Changes to the Document ........................8
+ 2.2.3. Solution Description ................................8
+ 2.3. Padding Issues .............................................8
+ 2.3.1. Description of the Problem ..........................8
+ 2.3.2. Text Changes to the Document ........................9
+ 2.3.3. Solution Description ...............................10
+ 2.4. Parameter Types across All Chunk Types ....................10
+ 2.4.1. Description of the Problem .........................10
+ 2.4.2. Text Changes to the Document .......................10
+ 2.4.3. Solution Description ...............................12
+ 2.5. Stream Parameter Clarification ............................12
+ 2.5.1. Description of the problem .........................12
+ 2.5.2. Text Changes to the Document .......................12
+ 2.5.3. Solution Description ...............................13
+ 2.6. Restarting Association Security Issue .....................13
+ 2.6.1. Description of the Problem .........................13
+ 2.6.2. Text Changes to the Document .......................14
+ 2.6.3. Solution Description ...............................18
+ 2.7. Implicit Ability to Exceed cwnd by PMTU-1 Bytes ...........19
+ 2.7.1. Description of the Problem .........................19
+ 2.7.2. Text Changes to the Document .......................19
+ 2.7.3. Solution Description ...............................19
+ 2.8. Issues with Fast Retransmit ...............................19
+ 2.8.1. Description of the Problem .........................19
+ 2.8.2. Text Changes to the Document .......................20
+ 2.8.3. Solution Description ...............................23
+ 2.9. Missing Statement about partial_bytes_acked Update ........24
+ 2.9.1. Description of the Problem .........................24
+ 2.9.2. Text Changes to the Document .......................24
+ 2.9.3. Solution Description ...............................25
+ 2.10. Issues with Heartbeating and Failure Detection ...........25
+ 2.10.1. Description of the Problem ........................25
+ 2.10.2. Text Changes to the Document ......................26
+ 2.10.3. Solution Description ..............................28
+ 2.11. Security interactions with firewalls .....................29
+ 2.11.1. Description of the Problem ........................29
+ 2.11.2. Text Changes to the Document ......................29
+ 2.11.3. Solution Description ..............................31
+ 2.12. Shutdown Ambiguity .......................................31
+ 2.12.1. Description of the Problem ........................31
+ 2.12.2. Text Changes to the Document ......................31
+ 2.12.3. Solution Description ..............................32
+ 2.13. Inconsistency in ABORT Processing ........................32
+ 2.13.1. Description of the Problem ........................32
+ 2.13.2. Text changes to the document ......................33
+ 2.13.3. Solution Description ..............................33
+
+
+
+Stewart, et al. Informational [Page 2]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 2.14. Cwnd Gated by Its Full Use ...............................34
+ 2.14.1. Description of the Problem ........................34
+ 2.14.2. Text Changes to the Document ......................34
+ 2.14.3. Solution Description ..............................36
+ 2.15. Window Probes in SCTP ....................................36
+ 2.15.1. Description of the Problem ........................36
+ 2.15.2. Text Changes to the Document ......................36
+ 2.15.3. Solution Description ..............................38
+ 2.16. Fragmentation and Path MTU Issues ........................39
+ 2.16.1. Description of the Problem ........................39
+ 2.16.2. Text Changes to the Document ......................39
+ 2.16.3. Solution Description ..............................40
+ 2.17. Initial Value of the Cumulative TSN Ack ..................40
+ 2.17.1. Description of the Problem ........................40
+ 2.17.2. Text Changes to the Document ......................40
+ 2.17.3. Solution Description ..............................41
+ 2.18. Handling of Address Parameters within the INIT or
+ INIT-ACK .................................................41
+ 2.18.1. Description of the Problem ........................41
+ 2.18.2. Text Changes to the Document ......................41
+ 2.18.3. Solution description ..............................42
+ 2.19. Handling of Stream Shortages .............................42
+ 2.19.1. Description of the Problem ........................42
+ 2.19.2. Text Changes to the Document ......................42
+ 2.19.3. Solution Description ..............................43
+ 2.20. Indefinite Postponement ..................................43
+ 2.20.1. Description of the Problem ........................43
+ 2.20.2. Text Changes to the Document ......................43
+ 2.20.3. Solution Description ..............................44
+ 2.21. User-Initiated Abort of an Association ...................44
+ 2.21.1. Description of the Problem ........................44
+ 2.21.2. Text changes to the document ......................44
+ 2.21.3. Solution Description ..............................50
+ 2.22. Handling of Invalid Initiate Tag of INIT-ACK .............50
+ 2.22.1. Description of the Problem ........................50
+ 2.22.2. Text Changes to the Document ......................50
+ 2.22.3. Solution Description ..............................51
+ 2.23. Sending an ABORT in Response to an INIT ..................51
+ 2.23.1. Description of the Problem ........................51
+ 2.23.2. Text Changes to the Document ......................51
+ 2.23.3. Solution Description ..............................52
+ 2.24. Stream Sequence Number (SSN) Initialization ..............52
+ 2.24.1. Description of the Problem ........................52
+ 2.24.2. Text Changes to the Document ......................52
+ 2.24.3. Solution Description ..............................53
+ 2.25. SACK Packet Format .......................................53
+ 2.25.1. Description of the Problem ........................53
+ 2.25.2. Text Changes to the Document ......................53
+
+
+
+Stewart, et al. Informational [Page 3]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 2.25.3. Solution Description ..............................53
+ 2.26. Protocol Violation Error Cause ...........................53
+ 2.26.1. Description of the Problem ........................53
+ 2.26.2. Text Changes to the Document ......................54
+ 2.26.3. Solution Description ..............................56
+ 2.27. Reporting of Unrecognized Parameters .....................56
+ 2.27.1. Description of the Problem ........................56
+ 2.27.2. Text Changes to the Document ......................56
+ 2.27.3. Solution Description ..............................57
+ 2.28. Handling of IP Address Parameters ........................58
+ 2.28.1. Description of the Problem ........................58
+ 2.28.2. Text Changes to the Document ......................58
+ 2.28.3. Solution Description ..............................58
+ 2.29. Handling of COOKIE ECHO Chunks When a TCB Exists .........59
+ 2.29.1. Description of the Problem ........................59
+ 2.29.2. Text Changes to the Document ......................59
+ 2.29.3. Solution Description ..............................59
+ 2.30. The Initial Congestion Window Size .......................59
+ 2.30.1. Description of the Problem ........................59
+ 2.30.2. Text Changes to the Document ......................60
+ 2.30.3. Solution Description ..............................61
+ 2.31. Stream Sequence Numbers in Figures .......................62
+ 2.31.1. Description of the Problem ........................62
+ 2.31.2. Text Changes to the Document ......................63
+ 2.31.3. Solution description ..............................67
+ 2.32. Unrecognized Parameters ..................................67
+ 2.32.1. Description of the Problem ........................67
+ 2.32.2. Text Changes to the Document ......................67
+ 2.32.3. Solution Description ..............................68
+ 2.33. Handling of Unrecognized Parameters ......................68
+ 2.33.1. Description of the Problem ........................68
+ 2.33.2. Text Changes to the Document ......................68
+ 2.33.3. Solution Description ..............................70
+ 2.34. Tie Tags .................................................70
+ 2.34.1. Description of the Problem ........................70
+ 2.34.2. Text Changes to the Document ......................70
+ 2.34.3. Solution Description ..............................72
+ 2.35. Port Number Verification in the COOKIE-ECHO ..............72
+ 2.35.1. Description of the Problem ........................72
+ 2.35.2. Text Changes to the Document ......................72
+ 2.35.3. Solution Description ..............................73
+ 2.36. Path Initialization ......................................74
+ 2.36.1. Description of the Problem ........................74
+ 2.36.2. Text Changes to the Document ......................74
+ 2.36.3. Solution Description ..............................76
+ 2.37. ICMP Handling Procedures .................................76
+ 2.37.1. Description of the Problem ........................76
+ 2.37.2. Text Changes to the Document ......................77
+
+
+
+Stewart, et al. Informational [Page 4]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 2.37.3. Solution Description ..............................79
+ 2.38. Checksum .................................................79
+ 2.38.1. Description of the problem ........................79
+ 2.38.2. Text Changes to the Document ......................79
+ 2.38.3. Solution Description ..............................86
+ 2.39. Retransmission Policy ....................................86
+ 2.39.1. Description of the Problem ........................86
+ 2.39.2. Text Changes to the Document ......................87
+ 2.39.3. Solution Description ..............................87
+ 2.40. Port Number 0 ............................................88
+ 2.40.1. Description of the Problem ........................88
+ 2.40.2. Text Changes to the Document ......................88
+ 2.40.3. Solution Description ..............................89
+ 2.41. T Bit ....................................................89
+ 2.41.1. Description of the Problem ........................89
+ 2.41.2. Text Changes to the Document ......................89
+ 2.41.3. Solution Description ..............................93
+ 2.42. Unknown Parameter Handling ...............................93
+ 2.42.1. Description of the Problem ........................93
+ 2.42.2. Text Changes to the Document ......................93
+ 2.42.3. Solution Description ..............................95
+ 2.43. Cookie Echo Chunk ........................................95
+ 2.43.1. Description of the Problem ........................95
+ 2.43.2. Text Changes to the Document ......................95
+ 2.43.3. Solution Description ..............................96
+ 2.44. Partial Chunks ...........................................96
+ 2.44.1. Description of the Problem ........................96
+ 2.44.2. Text Changes to the Document ......................96
+ 2.44.3. Solution Description ..............................97
+ 2.45. Non-unicast Addresses ....................................97
+ 2.45.1. Description of the Problem ........................97
+ 2.45.2. Text Changes to the Document ......................97
+ 2.45.3. Solution Description ..............................98
+ 2.46. Processing of ABORT Chunks ...............................98
+ 2.46.1. Description of the Problem ........................98
+ 2.46.2. Text Changes to the Document ......................98
+ 2.46.3. Solution Description ..............................98
+ 2.47. Sending of ABORT Chunks ..................................99
+ 2.47.1. Description of the Problem ........................99
+ 2.47.2. Text Changes to the Document ......................99
+ 2.47.3. Solution Description ..............................99
+ 2.48. Handling of Supported Address Types Parameter ............99
+ 2.48.1. Description of the Problem ........................99
+ 2.48.2. Text Changes to the Document .....................100
+ 2.48.3. Solution Description .............................100
+ 2.49. Handling of Unexpected Parameters .......................101
+ 2.49.1. Description of the Problem .......................101
+ 2.49.2. Text Changes to the Document .....................101
+
+
+
+Stewart, et al. Informational [Page 5]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 2.49.3. Solution Description .............................102
+ 2.50. Payload Protocol Identifier .............................102
+ 2.50.1. Description of the Problem .......................102
+ 2.50.2. Text Changes to the Document .....................103
+ 2.50.3. Solution Description .............................103
+ 2.51. Karn's Algorithm ........................................104
+ 2.51.1. Description of the Problem .......................104
+ 2.51.2. Text Changes to the Document .....................104
+ 2.51.3. Solution Description .............................104
+ 2.52. Fast Retransmit Algorithm ...............................104
+ 2.52.1. Description of the Problem .......................104
+ 2.52.2. Text Changes to the Document .....................105
+ 2.52.3. Solution Description .............................105
+ 3. Security Considerations .......................................105
+ 4. Acknowledgements ..............................................106
+ 5. IANA Considerations ...........................................106
+ 6. Normative References ..........................................106
+
+1. Introduction
+
+ This document contains a compilation of all defects found up until
+ the publishing of this document for the Stream Control Transmission
+ Protocol (SCTP), RFC 2960 [5]. These defects may be of an editorial
+ or technical nature. This document may be thought of as a companion
+ document to be used in the implementation of SCTP to clarify errors
+ in the original SCTP document.
+
+ This document provides a history of the changes that will be compiled
+ into RFC 2960's [5] BIS document. Each error will be detailed within
+ this document in the form of
+
+ o the problem description,
+
+ o the text quoted from RFC 2960 [5],
+
+ o the replacement text that should be placed into the BIS document,
+ and
+
+ o a description of the solution.
+
+ This document is a historical record of sequential changes what have
+ been found necessary at various interop events and through discussion
+ on this list.
+
+ Note that because some text is changed several times, the last delta
+ for a text in the document is the erratum for that text in RFC 2960.
+
+
+
+
+
+Stewart, et al. Informational [Page 6]
+
+RFC 4460 SCTP Errata April 2006
+
+
+1.1. Conventions
+
+ The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
+ SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when
+ they appear in this document, are to be interpreted as described in
+ RFC 2119 [2].
+
+2. Corrections to RFC 2960
+
+2.1. Incorrect Error Type During Chunk Processing.
+
+2.1.1. Description of the Problem
+
+ A typo was discovered in RFC 2960 [5] that incorrectly specifies an
+ action to be taken when processing chunks of unknown identity.
+
+2.1.2. Text changes to the document
+
+ ---------
+ Old text: (Section 3.2)
+ ---------
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ ---------
+ New text: (Section 3.2)
+ ---------
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ chunk in an 'Unrecognized Chunk Type'.
+
+2.1.3. Solution Description
+
+ The receiver of an unrecognized chunk should not send a 'parameter'
+ error but instead should send the appropriate chunk error as
+ described above.
+
+2.2. Parameter Processing Issue
+
+2.2.1. Description of the Problem
+
+ A typographical error was introduced through an improper cut and
+ paste in the use of the upper two bits to describe proper handling of
+ unknown parameters.
+
+
+
+Stewart, et al. Informational [Page 7]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.2.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP packet and discard it; do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ ---------
+ New text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP chunk and discard it, do not process
+ any further parameters within this chunk.
+
+ 01 - Stop processing this SCTP chunk and discard it, do not process
+ any further parameters within this chunk, and report the
+ unrecognized parameter in an 'Unrecognized Parameter Type' (in
+ either an ERROR or in the INIT ACK).
+
+2.2.3. Solution Description
+
+ It was always the intent to stop processing at the level one was at
+ in an unknown chunk or parameter with the upper bit set to 0. Thus,
+ if you are processing a chunk, you should drop the packet. If you
+ are processing a parameter, you should drop the chunk.
+
+2.3. Padding Issues
+
+2.3.1. Description of the Problem
+
+ A problem was found when a Chunk terminated in a TLV parameter. If
+ this last TLV was not on a 32-bit boundary (as required), there was
+ confusion as to whether the last padding was included in the chunk
+ length.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 8]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.3.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.2)
+ ---------
+
+ Chunk Length: 16 bits (unsigned integer)
+
+ This value represents the size of the chunk in bytes including the
+ Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+ Therefore, if the Chunk Value field is zero-length, the Length
+ field will be set to 4. The Chunk Length field does not count any
+ padding.
+
+ Chunk Value: variable length
+
+ The Chunk Value field contains the actual information to be
+ transferred in the chunk. The usage and format of this field is
+ dependent on the Chunk Type.
+
+ The total length of a chunk (including Type, Length and Value fields)
+ MUST be a multiple of 4 bytes. If the length of the chunk is not a
+ multiple of 4 bytes, the sender MUST pad the chunk with all zero
+ bytes and this padding is not included in the chunk length field.
+ The sender should never pad with more than 3 bytes. The receiver
+ MUST ignore the padding bytes.
+
+ ---------
+ New text: (Section 3.2)
+ ---------
+
+ Chunk Length: 16 bits (unsigned integer)
+
+ This value represents the size of the chunk in bytes, including
+ the Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+ Therefore, if the Chunk Value field is zero-length, the Length
+ field will be set to 4. The Chunk Length field does not count any
+ chunk padding.
+
+ Chunks (including Type, Length, and Value fields) are padded out
+ by the sender with all zero bytes to be a multiple of 4 bytes
+ long. This padding MUST NOT be more than 3 bytes in total. The
+ Chunk Length value does not include terminating padding of the
+ chunk. However, it does include padding of any variable-length
+ parameter except the last parameter in the chunk. The receiver
+ MUST ignore the padding.
+
+
+
+
+
+Stewart, et al. Informational [Page 9]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ Note: A robust implementation should accept the Chunk whether or
+ not the final padding has been included in the Chunk Length.
+
+ Chunk Value: variable length
+
+ The Chunk Value field contains the actual information to be
+ transferred in the chunk. The usage and format of this field is
+ dependent on the Chunk Type.
+
+ The total length of a chunk (including Type, Length, and Value
+ fields) MUST be a multiple of 4 bytes. If the length of the chunk is
+ not a multiple of 4 bytes, the sender MUST pad the chunk with all
+ zero bytes, and this padding is not included in the chunk length
+ field. The sender should never pad with more than 3 bytes. The
+ receiver MUST ignore the padding bytes.
+
+2.3.3. Solution Description
+
+ The above text makes clear that the padding of the last parameter is
+ not included in the Chunk Length field. It also clarifies that the
+ padding of parameters that are not the last one must be counted in
+ the Chunk Length field.
+
+2.4. Parameter Types across All Chunk Types
+
+2.4.1. Description of the Problem
+
+ A problem was noted when multiple errors are needed to be sent
+ regarding unknown or unrecognized parameters. Since often the error
+ type does not hold the chunk type field, it may become difficult to
+ tell which error was associated with which chunk.
+
+2.4.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.2.1)
+ ---------
+
+ The actual SCTP parameters are defined in the specific SCTP chunk
+ sections. The rules for IETF-defined parameter extensions are
+ defined in Section 13.2.
+
+ ---------
+ New text: (Section 3.2.1)
+ ---------
+
+ The actual SCTP parameters are defined in the specific SCTP chunk
+ sections. The rules for IETF-defined parameter extensions are
+
+
+
+Stewart, et al. Informational [Page 10]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ defined in Section 13.2. Note that a parameter type MUST be unique
+ across all chunks. For example, the parameter type '5' is used to
+ represent an IPv4 address (see Section 3.3.2). The value '5' then is
+ reserved across all chunks to represent an IPv4 address and MUST NOT
+ be reused with a different meaning in any other chunk.
+
+ ---------
+ Old text: (Section 13.2)
+ ---------
+
+ 13.2 IETF-defined Chunk Parameter Extension
+
+ The assignment of new chunk parameter type codes is done through an
+ IETF Consensus action as defined in [RFC2434]. Documentation of the
+ chunk parameter MUST contain the following information:
+
+ a) Name of the parameter type.
+
+ b) Detailed description of the structure of the parameter field.
+ This structure MUST conform to the general type-length-value
+ format described in Section 3.2.1.
+
+ c) Detailed definition of each component of the parameter type.
+
+ d) Detailed description of the intended use of this parameter type,
+ and an indication of whether and under what circumstances multiple
+ instances of this parameter type may be found within the same
+ chunk.
+
+ ---------
+ New text: (Section 13.2)
+ ---------
+
+ 13.2. IETF-defined Chunk Parameter Extension
+
+ The assignment of new chunk parameter type codes is done through an
+ IETF Consensus action, as defined in [RFC2434]. Documentation of the
+ chunk parameter MUST contain the following information:
+
+ a) Name of the parameter type.
+
+ b) Detailed description of the structure of the parameter field.
+ This structure MUST conform to the general type-length-value
+ format described in Section 3.2.1.
+
+ c) Detailed definition of each component of the parameter type.
+
+
+
+
+
+Stewart, et al. Informational [Page 11]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ d) Detailed description of the intended use of this parameter type,
+ and an indication of whether and under what circumstances multiple
+ instances of this parameter type may be found within the same
+ chunk.
+
+ e) Each parameter type MUST be unique across all chunks.
+
+2.4.3. Solution Description
+
+ By having all parameters unique across all chunk assignments (the
+ current assignment policy), no ambiguity exists as to what a
+ parameter means in different contexts. The trade-off for this is a
+ smaller parameter space, i.e., 65,536 parameters versus 65,536 *
+ Number-of- chunks.
+
+2.5. Stream Parameter Clarification
+
+2.5.1. Description of the problem
+
+ A problem was found where the specification is unclear on the
+ legality of an endpoint asking for more stream resources than were
+ allowed in the MIS value of the INIT. In particular, the value in
+ the INIT ACK requested in its OS value was larger than the MIS value
+ received in the INIT chunk. This behavior is illegal, yet it was
+ unspecified in RFC 2960 [5]
+
+2.5.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.3)
+ ---------
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT ACK
+ chunk wishes to create in this association. The value of 0 MUST
+ NOT be used.
+
+ Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+ destroy the association discarding its TCB.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 12]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.3.3)
+ ---------
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT ACK
+ chunk wishes to create in this association. The value of 0 MUST
+ NOT be used, and the value MUST NOT be greater than the MIS value
+ sent in the INIT chunk.
+
+ Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+ destroy the association, discarding its TCB.
+
+2.5.3. Solution Description
+
+ The change in wording, above, changes it so that a responder to an
+ INIT chunk does not specify more streams in its OS value than were
+ represented to it in the MIS value, i.e., its maximum.
+
+2.6. Restarting Association Security Issue
+
+2.6.1. Description of the Problem
+
+ A security problem was found when a restart occurs. It is possible
+ for an intruder to send an INIT to an endpoint of an existing
+ association. In the INIT the intruder would list one or more of the
+ current addresses of an association and its own. The normal restart
+ procedures would then occur, and the intruder would have hijacked an
+ association.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 13]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.6.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 14]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+ 11 Restart of an Association with New Addresses
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields.
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.11 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+ ---------
+ New text: (Note no old text, new error cause added in section 3.3.10)
+ ---------
+
+ 3.3.10.11. Restart of an Association with New Addresses (11)
+
+ Cause of error
+ --------------
+ Restart of an association with new addresses: An INIT was received
+ on an existing association. But the INIT added addresses to the
+ association that were previously NOT part of the association. The
+ new addresses are listed in the error code. This ERROR is normally
+ sent as part of an ABORT refusing the INIT (see Section 5.2).
+
+
+
+
+
+
+Stewart, et al. Informational [Page 15]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=11 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / New Address TLVs /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: Each New Address TLV is an exact copy of the TLV
+ that was found in the INIT chunk that was new, including the
+ Parameter Type and the Parameter length.
+
+ ---------
+ Old text: (Section 5.2.1)
+ ---------
+
+ Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
+ endpoint MUST respond with an INIT ACK using the same parameters it
+ sent in its original INIT chunk (including its Initiation Tag,
+ unchanged). These original parameters are combined with those from
+ the newly received INIT chunk. The endpoint shall also generate a
+ State Cookie with the INIT ACK. The endpoint uses the parameters
+ sent in its INIT to calculate the State Cookie.
+
+ ---------
+ New text: (Section 5.2.1)
+ ---------
+
+ Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST
+ respond with an INIT ACK using the same parameters it sent in its
+ original INIT chunk (including its Initiation Tag, unchanged). When
+ responding, the endpoint MUST send the INIT ACK back to the same
+ address that the original INIT (sent by this endpoint) was sent to.
+
+ Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
+ respond with an INIT ACK using the same parameters it sent in its
+ original INIT chunk (including its Initiation Tag, unchanged),
+ provided that no NEW address has been added to the forming
+ association. If the INIT message indicates that a new address has
+ been added to the association, then the entire INIT MUST be
+ discarded, and NO changes should be made to the existing association.
+ An ABORT SHOULD be sent in response that MAY include the error
+ 'Restart of an association with new addresses'. The error SHOULD
+ list the addresses that were added to the restarting association.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 16]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ When responding in either state (COOKIE-WAIT or COOKIE-ECHOED) with
+ an INIT ACK, the original parameters are combined with those from the
+ newly received INIT chunk. The endpoint shall also generate a State
+ Cookie with the INIT ACK. The endpoint uses the parameters sent in
+ its INIT to calculate the State Cookie.
+
+ ---------
+ Old text: (Section 5.2.2)
+ ---------
+
+ 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
+ COOKIE-WAIT and SHUTDOWN-ACK-SENT
+
+ Unless otherwise stated, upon reception of an unexpected INIT for
+ this association, the endpoint shall generate an INIT ACK with a
+ State Cookie. In the outbound INIT ACK the endpoint MUST copy its
+ current Verification Tag and peer's Verification Tag into a reserved
+ place within the state cookie. We shall refer to these locations as
+ the Peer's-Tie-Tag and the Local-Tie-Tag. The outbound SCTP packet
+ containing this INIT ACK MUST carry a Verification Tag value equal to
+ the Initiation Tag found in the unexpected INIT. And the INIT ACK
+ MUST contain a new Initiation Tag (randomly generated see Section
+ 5.3.1). Other parameters for the endpoint SHOULD be copied from the
+ existing parameters of the association (e.g., number of outbound
+ streams) into the INIT ACK and cookie.
+
+ After sending out the INIT ACK, the endpoint shall take no further
+ actions, i.e., the existing association, including its current state,
+ and the corresponding TCB MUST NOT be changed.
+
+ Note: Only when a TCB exists and the association is not in a COOKIE-
+ WAIT state are the Tie-Tags populated. For a normal association INIT
+ (i.e., the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be
+ set to 0 (indicating that no previous TCB existed). The INIT ACK and
+ State Cookie are populated as specified in section 5.2.1.
+
+ ---------
+ New text: (Section 5.2.2)
+ ---------
+
+ 5.2.2. Unexpected INIT in States Other Than CLOSED, COOKIE-ECHOED,
+ COOKIE-WAIT, and SHUTDOWN-ACK-SENT
+
+ Unless otherwise stated, upon receipt of an unexpected INIT for this
+ association, the endpoint shall generate an INIT ACK with a State
+ Cookie. Before responding, the endpoint MUST check to see if the
+ unexpected INIT adds new addresses to the association. If new
+ addresses are added to the association, the endpoint MUST respond
+
+
+
+Stewart, et al. Informational [Page 17]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ with an ABORT, copying the 'Initiation Tag' of the unexpected INIT
+ into the 'Verification Tag' of the outbound packet carrying the
+ ABORT. In the ABORT response, the cause of error MAY be set to
+ 'restart of an association with new addresses'. The error SHOULD
+ list the addresses that were added to the restarting association.
+
+ If no new addresses are added, when responding to the INIT in the
+ outbound INIT ACK, the endpoint MUST copy its current Verification
+ Tag and peer's Verification Tag into a reserved place within the
+ state cookie. We shall refer to these locations as the Peer's-Tie-
+ Tag and the Local-Tie-Tag. The outbound SCTP packet containing this
+ INIT ACK MUST carry a Verification Tag value equal to the Initiation
+ Tag found in the unexpected INIT. And the INIT ACK MUST contain a
+ new Initiation Tag (randomly generated; see Section 5.3.1). Other
+ parameters for the endpoint SHOULD be copied from the existing
+ parameters of the association (e.g., number of outbound streams) into
+ the INIT ACK and cookie.
+
+ After sending out the INIT ACK or ABORT, the endpoint shall take no
+ further actions; i.e., the existing association, including its
+ current state, and the corresponding TCB MUST NOT be changed.
+
+ Note: Only when a TCB exists and the association is not in a COOKIE-
+ WAIT or SHUTDOWN-ACK-SENT state are the Tie-Tags populated with a
+ value other than 0. For a normal association INIT (i.e., the
+ endpoint is in the CLOSED state), the Tie-Tags MUST be set to 0
+ (indicating that no previous TCB existed).
+
+2.6.3. Solution Description
+
+ A new error code is being added, along with specific instructions to
+ send back an ABORT to a new association in a restart case or
+ collision case, where new addresses have been added. The error code
+ can be used by a legitimate restart to inform the endpoint that it
+ has made a software error in adding a new address. The endpoint then
+ can choose to wait until the OOTB ABORT tears down the old
+ association, or to restart without the new address.
+
+ Also, the note at the end of Section 5.2.2 explaining the use of the
+ Tie-Tags was modified to properly explain the states in which the
+ Tie-Tags should be set to a value different than 0.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 18]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.7. Implicit Ability to Exceed cwnd by PMTU-1 Bytes
+
+2.7.1. Description of the Problem
+
+ Some implementations were having difficulty growing their cwnd. This
+ was due to an improper enforcement of the congestion control rules.
+ The rules, as written, provided for a slop over of the cwnd value.
+ Without this slop over, the sender would appear NOT to be using its
+ full cwnd value and thus would never increase it.
+
+2.7.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.1)
+ ---------
+
+ B) At any given time, the sender MUST NOT transmit new data to a
+ given transport address if it has cwnd or more bytes of data
+ outstanding to that transport address.
+
+ ---------
+ New text: (Section 6.1)
+ ---------
+
+ B) At any given time, the sender MUST NOT transmit new data to a
+ given transport address if it has cwnd or more bytes of data
+ outstanding to that transport address. The sender may exceed cwnd
+ by up to (PMTU-1) bytes on a new transmission if the cwnd is not
+ currently exceeded.
+
+2.7.3. Solution Description
+
+ The text changes make clear the ability to go over the cwnd value by
+ no more than (PMTU-1) bytes.
+
+2.8. Issues with Fast Retransmit
+
+2.8.1. Description of the Problem
+
+ Several problems were found in the current specification of fast
+ retransmit. The current wording did not require GAP ACK blocks to be
+ sent, even though they are essential to the workings of SCTP's
+ congestion control. The specification left unclear how to handle the
+ fast retransmit cycle, having the implementation wait on the cwnd to
+ retransmit a TSN that was marked for fast retransmit. No limit was
+ placed on how many times a TSN could be fast retransmitted. Fast
+ Recovery was not specified, causing the congestion window to be
+ reduced drastically when there are multiple losses in a single RTT.
+
+
+
+Stewart, et al. Informational [Page 19]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.8.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.2)
+ ---------
+
+ Acknowledgements MUST be sent in SACK chunks unless shutdown was
+ requested by the ULP in which case an endpoint MAY send an
+ acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge
+ the reception of multiple DATA chunks. See Section 3.3.4 for SACK
+ chunk format. In particular, the SCTP endpoint MUST fill in the
+ Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+ valid DATA chunk) it has received. Any received DATA chunks with TSN
+ greater than the value in the Cumulative TSN Ack field SHOULD also be
+ reported in the Gap Ack Block fields.
+
+ ---------
+ New text: (Section 6.2)
+ ---------
+
+ Acknowledegments MUST be sent in SACK chunks unless shutdown was
+ requested by the ULP, in which case an endpoint MAY send an
+ acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge
+ the reception of multiple DATA chunks. See Section 3.3.4 for SACK
+ chunk format. In particular, the SCTP endpoint MUST fill in the
+ Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+ valid DATA chunk) it has received. Any received DATA chunks with
+ TSN greater than the value in the Cumulative TSN Ack field are
+ reported in the Gap Ack Block fields. The SCTP endpoint MUST
+ report as many Gap Ack Blocks as can fit in a single SACK
+ chunk limited by the current path MTU.
+
+ ---------
+ Old text: (Section 6.2.1)
+ ---------
+
+ D) Any time a SACK arrives, the endpoint performs the following:
+
+ i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+ Point, then drop the SACK. Since Cumulative TSN Ack is
+ monotonically increasing, a SACK whose Cumulative TSN Ack is
+ less than the Cumulative TSN Ack Point indicates an out-of-
+ order SACK.
+
+ ii) Set rwnd equal to the newly received a_rwnd minus the
+ number of bytes still outstanding after processing the
+ Cumulative TSN Ack and the Gap Ack Blocks.
+
+
+
+
+Stewart, et al. Informational [Page 20]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ iii) If the SACK is missing a TSN that was previously
+ acknowledged via a Gap Ack Block (e.g., the data receiver
+ reneged on the data), then mark the corresponding DATA chunk
+ as available for retransmit: Mark it as missing for fast
+ retransmit as described in Section 7.2.4 and if no
+ retransmit timer is running for the destination address
+ to which the DATA chunk was originally transmitted, then
+ T3-rtx is started for that destination address.
+
+ ---------
+ New text: (Section 6.2.1)
+ ---------
+
+ D) Any time a SACK arrives, the endpoint performs the following:
+
+ i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+ Point, then drop the SACK. Since Cumulative TSN Ack is
+ monotonically increasing, a SACK whose Cumulative TSN Ack is
+ less than the Cumulative TSN Ack Point indicates an out-of-
+ order SACK.
+
+ ii) Set rwnd equal to the newly received a_rwnd minus the
+ number of bytes still outstanding after processing the
+ Cumulative TSN Ack and the Gap Ack Blocks.
+
+ iii) If the SACK is missing a TSN that was previously
+ acknowledged via a Gap Ack Block (e.g., the data receiver
+ reneged on the data), then consider the corresponding DATA
+ that might be possibly missing: Count one miss indication
+ towards fast retransmit as described in Section 7.2.4, and
+ if no retransmit timer is running for the destination
+ address to which the DATA chunk was originally transmitted,
+ then T3-rtx is started for that destination address.
+
+ iv) If the Cumulative TSN Ack matches or exceeds the Fast
+ Recovery exitpoint (Section 7.2.4), Fast Recovery is exited.
+
+ ---------
+ Old text: (Section 7.2.4)
+ ---------
+
+ Whenever an endpoint receives a SACK that indicates some TSN(s)
+ missing, it SHOULD wait for 3 further miss indications (via
+ subsequent SACK's) on the same TSN(s) before taking action with
+ regard to Fast Retransmit.
+
+ When the TSN(s) is reported as missing in the fourth consecutive
+ SACK, the data sender shall:
+
+
+
+Stewart, et al. Informational [Page 21]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 1) Mark the missing DATA chunk(s) for retransmission,
+
+ 2) Adjust the ssthresh and cwnd of the destination address(es) to
+ which the missing DATA chunks were last sent, according to the
+ formula described in Section 7.2.3.
+
+ 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+ marked for retransmission will fit into a single packet, subject
+ to constraint of the path MTU of the destination transport address
+ to which the packet is being sent. Call this value K. Retransmit
+ those K DATA chunks in a single packet.
+
+ 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest
+ outstanding TSN number sent to that address, or the endpoint is
+ retransmitting the first outstanding DATA chunk sent to that
+ address.
+
+ Note: Before the above adjustments, if the received SACK also
+ acknowledges new DATA chunks and advances the Cumulative TSN Ack
+ Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2
+ must be applied first.
+
+ A straightforward implementation of the above keeps a counter for
+ each TSN hole reported by a SACK. The counter increments for each
+ consecutive SACK reporting the TSN hole. After reaching 4 and
+ starting the fast retransmit procedure, the counter resets to 0.
+ Because cwnd in SCTP indirectly bounds the number of outstanding
+ TSN's, the effect of TCP fast-recovery is achieved automatically with
+ no adjustment to the congestion control window size.
+
+ ---------
+ New text: (Section 7.2.4)
+ ---------
+
+ Whenever an endpoint receives a SACK that indicates that some TSNs
+ are missing, it SHOULD wait for 3 further miss indications (via
+ subsequent SACKs) on the same TSN(s) before taking action with
+ regard to Fast Retransmit.
+
+ Miss indications SHOULD follow the HTNA (Highest TSN Newly
+ Acknowledged) algorithm. For each incoming SACK, miss
+ indications are incremented only for missing TSNs prior to
+ the highest TSN newly acknowledged in the SACK. A newly
+ acknowledged DATA chunk is one not previously acknowledged
+ in a SACK. If an endpoint is in Fast Recovery and a SACK
+ arrives that advances the Cumulative TSN Ack Point, the
+ miss indications are incremented for all TSNs reported
+ missing in the SACK.
+
+
+
+Stewart, et al. Informational [Page 22]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ When the fourth consecutive miss indication is received for a TSN(s),
+ the data sender shall do the following:
+
+ 1) Mark the DATA chunk(s) with four miss indications for
+ retransmission.
+
+ 2) If not in Fast Recovery, adjust the ssthresh and cwnd of the
+ destination address(es) to which the missing DATA chunks were
+ last sent, according to the formula described in Section 7.2.3.
+
+ 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+ marked for retransmission will fit into a single packet, subject
+ to constraint of the path MTU of the destination transport address
+ to which the packet is being sent. Call this value K. Retransmit
+ those K DATA chunks in a single packet. When a Fast Retransmit is
+ being performed, the sender SHOULD ignore the value of cwnd and
+ SHOULD NOT delay retransmission for this single packet.
+
+ 4) Restart T3-rtx timer only if the last SACK acknowledged the lowest
+ outstanding TSN number sent to that address, or the endpoint is
+ retransmitting the first outstanding DATA chunk sent to that
+ address.
+
+ 5) Mark the DATA chunk(s) as being fast retransmitted and thus
+ ineligible for a subsequent fast retransmit. Those TSNs marked
+ for retransmission due to the Fast Retransmit algorithm that
+ did not fit in the sent datagram carrying K other TSNs are also
+ marked as ineligible for a subsequent fast retransmit. However,
+ as they are marked for retransmission they will be retransmitted
+ later on as soon as cwnd allows.
+
+ 6) If not in Fast Recovery, enter Fast Recovery and mark the highest
+ outstanding TSN as the Fast Recovery exit point. When a SACK
+ acknowledges all TSNs up to and including this exit point, Fast
+ Recovery is exited. While in Fast Recovery, the ssthresh and cwnd
+ SHOULD NOT change for any destinations due to a subsequent Fast
+ Recovery event (i.e., one SHOULD NOT reduce the cwnd further due
+ to a subsequent fast retransmit).
+
+ Note: Before the above adjustments, if the received SACK also
+ acknowledges new DATA chunks and advances the Cumulative TSN Ack
+ Point, the cwnd adjustment rules defined in Sections 7.2.1 and 7.2.2
+ must be applied first.
+
+2.8.3. Solution Description
+
+ The effect of the above wording changes are as follows:
+
+
+
+
+Stewart, et al. Informational [Page 23]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ o It requires with a MUST the sending of GAP Ack blocks instead of
+ the current RFC 2960 [5] SHOULD.
+
+ o It allows a TSN being Fast Retransmitted (FR) to be sent only once
+ via FR.
+
+ o It ends the delay in waiting for the flight size to drop when a
+ TSN is identified as being ready to FR.
+
+ o It changes the way chunks are marked during fast retransmit, so
+ that only new reports are counted.
+
+ o It introduces a Fast Recovery period to avoid multiple congestion
+ window reductions when there are multiple losses in a single RTT
+ (as shown by Caro et al. [3]).
+
+ These changes will effectively allow SCTP to follow a similar model
+ as TCP+SACK in the handling of Fast Retransmit.
+
+2.9. Missing Statement about partial_bytes_acked Update
+
+2.9.1. Description of the Problem
+
+ SCTP uses four control variables to regulate its transmission rate:
+ rwnd, cwnd, ssthresh, and partial_bytes_acked. Upon detection of
+ packet losses from SACK, or when the T3-rtx timer expires on an
+ address, cwnd and ssthresh should be updated as stated in Section
+ 7.2.3. However, that section should also clarify that
+ partial_bytes_acked must be updated as well; it has to be reset to 0.
+
+2.9.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 7.2.3)
+ ---------
+
+ 7.2.3 Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), An
+ endpoint should do the following:
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = ssthresh
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform slow
+ start by:
+
+
+
+Stewart, et al. Informational [Page 24]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = 1*MTU
+
+ ---------
+ New text: (Section 7.2.3)
+ ---------
+
+ 7.2.3. Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), an
+ endpoint should do the following if not in Fast Recovery:
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = ssthresh
+ partial_bytes_acked = 0
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform slow
+ start by
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = 1*MTU
+ partial_bytes_acked = 0
+
+2.9.3. Solution Description
+
+ The missing text added solves the doubts about what to do with
+ partial_bytes_acked in the situations stated in Section 7.2.3, making
+ clear that, along with ssthresh and cwnd, partial_bytes_acked should
+ also be updated by being reset to 0.
+
+2.10. Issues with Heartbeating and Failure Detection
+
+2.10.1. Description of the Problem
+
+ Five basic problems have been discovered with the current heartbeat
+ procedures:
+
+ o The current specification does not specify that you should count a
+ failed heartbeat as an error against the overall association.
+
+ o The current specification is not specific as to when you start
+ sending heartbeats and when you should stop.
+
+ o The current specification is not specific as to when you should
+ respond to heartbeats.
+
+
+
+
+Stewart, et al. Informational [Page 25]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ o When responding to a Heartbeat, it is unclear what to do if more
+ than a single TLV is present.
+
+ o The jitter applied to a heartbeat was meant to be a small variance
+ of the RTO and is currently a wide variance, due to the default
+ delay time and incorrect wording within the RFC.
+
+2.10.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 8.1)
+ ---------
+
+ 8.1 Endpoint Failure Detection
+
+ An endpoint shall keep a counter on the total number of consecutive
+ retransmissions to its peer (including retransmissions to all the
+ destination transport addresses of the peer if it is multi-homed).
+ If the value of this counter exceeds the limit indicated in the
+ protocol parameter 'Association.Max.Retrans', the endpoint shall
+ consider the peer endpoint unreachable and shall stop transmitting
+ any more data to it (and thus the association enters the CLOSED
+ state). In addition, the endpoint shall report the failure to the
+ upper layer, and optionally report back all outstanding user data
+ remaining in its outbound queue. The association is automatically
+ closed when the peer endpoint becomes unreachable.
+
+ The counter shall be reset each time a DATA chunk sent to that peer
+ endpoint is acknowledged (by the reception of a SACK), or a
+ HEARTBEAT-ACK is received from the peer endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 26]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 8.1)
+ ---------
+
+ 8.1. Endpoint Failure Detection
+
+ An endpoint shall keep a counter on the total number of consecutive
+ retransmissions to its peer (this includes retransmissions to all the
+ destination transport addresses of the peer if it is multi-homed),
+ including unacknowledged HEARTBEAT Chunks. If the value of this
+ counter exceeds the limit indicated in the protocol parameter
+ 'Association.Max.Retrans', the endpoint shall consider the peer
+ endpoint unreachable and shall stop transmitting any more data to it
+ (and thus the association enters the CLOSED state). In addition, the
+ endpoint MAY report the failure to the upper layer and optionally
+ report back all outstanding user data remaining in its outbound
+ queue. The association is automatically closed when the peer
+ endpoint becomes unreachable.
+
+ The counter shall be reset each time a DATA chunk sent to that peer
+ endpoint is acknowledged (by the reception of a SACK), or a
+ HEARTBEAT-ACK is received from the peer endpoint.
+
+
+ ---------
+ Old text: (Section 8.3)
+ ---------
+
+ 8.3 Path Heartbeat
+
+ By default, an SCTP endpoint shall monitor the reachability of the
+ idle destination transport address(es) of its peer by sending a
+ HEARTBEAT chunk periodically to the destination transport
+ address(es).
+
+ ---------
+ New text: (Section 8.3)
+ ---------
+
+ 8.3 Path Heartbeat
+
+ By default, an SCTP endpoint SHOULD monitor the reachability of the
+ idle destination transport address(es) of its peer by sending a
+ HEARTBEAT chunk periodically to the destination transport
+ address(es). HEARTBEAT sending MAY begin upon reaching the
+ ESTABLISHED state and is discontinued after sending either SHUTDOWN
+ or SHUTDOWN-ACK. A receiver of a HEARTBEAT MUST respond to a
+ HEARTBEAT with a HEARTBEAT-ACK after entering the COOKIE-ECHOED state
+
+
+
+Stewart, et al. Informational [Page 27]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ (INIT sender) or the ESTABLISHED state (INIT receiver), up until
+ reaching the SHUTDOWN-SENT state (SHUTDOWN sender) or the SHUTDOWN-
+ ACK-SENT state (SHUTDOWN receiver).
+
+
+ ---------
+ Old text: (Section 8.3)
+ ---------
+
+ The receiver of the HEARTBEAT should immediately respond with a
+ HEARTBEAT ACK that contains the Heartbeat Information field copied
+ from the received HEARTBEAT chunk.
+
+ ---------
+ New text: (Section 8.3)
+ ---------
+
+ The receiver of the HEARTBEAT should immediately respond with a
+ HEARTBEAT ACK that contains the Heartbeat Information TLV, together
+ with any other received TLVs, copied unchanged from the received
+ HEARTBEAT chunk.
+
+
+ ---------
+ Old text: (Section 8.3)
+ ---------
+
+ On an idle destination address that is allowed to heartbeat, a
+ HEARTBEAT chunk is RECOMMENDED to be sent once per RTO of that
+ destination address plus the protocol parameter 'HB.interval' , with
+ jittering of +/- 50%, and exponential back-off of the RTO if the
+ previous HEARTBEAT is unanswered.
+
+ ---------
+ New text: (Section 8.3)
+ ---------
+
+ On an idle destination address that is allowed to heartbeat, it is
+ recommended that a HEARTBEAT chunk is sent once per RTO of that
+ destination address plus the protocol parameter 'HB.interval', with
+ jittering of +/- 50% of the RTO value, and exponential back-off of
+ the RTO if the previous HEARTBEAT is unanswered.
+
+2.10.3. Solution Description
+
+ The above text provides guidance as to how to respond to the five
+ issues mentioned in Section 2.10.1. In particular, the wording
+ changes provide guidance as to when to start and stop heartbeating,
+
+
+
+Stewart, et al. Informational [Page 28]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ how to respond to a heartbeat with extra parameters, and it clarifies
+ the error counting procedures for the association.
+
+2.11. Security interactions with firewalls
+
+2.11.1. Description of the Problem
+
+ When dealing with firewalls, it is advantageous for the firewall to
+ be able to properly determine the initial startup sequence of a
+ reliable transport protocol. With this in mind, the following text
+ is to be added to SCTP's security section.
+
+2.11.2. Text Changes to the Document
+
+ ---------
+ New text: (no old text, new section added)
+ ---------
+
+ 11.4 SCTP Interactions with Firewalls
+
+ It is helpful for some firewalls if they can inspect
+ just the first fragment of a fragmented SCTP packet and unambiguously
+ determine whether it corresponds to an INIT chunk (for further
+ information, please refer to RFC1858). Accordingly, we
+ stress the requirements, stated in 3.1, that (1) an INIT chunk MUST
+ NOT be bundled with any other chunk in a packet, and (2) a packet
+ containing an INIT chunk MUST have a zero Verification Tag.
+ Furthermore, we require that the receiver of an INIT chunk MUST
+ enforce these rules by silently discarding an arriving packet with an
+ INIT chunk that is bundled with other chunks.
+
+ ---------
+ Old text: (Section 18)
+ ---------
+
+ 18. Bibliography
+
+ [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+ Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+ [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP, Computer Communications Review,
+ V. 26 N. 3, July 1996, pp. 5-21.
+
+ [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for
+ Security", RFC 1750, December 1994.
+
+
+
+
+
+Stewart, et al. Informational [Page 29]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, March 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management
+ Protocol", RFC 2522, March 1999.
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+ "TCP Congestion Control with a Misbehaving Receiver", ACM
+ Computer Communication Review, 29(5), October 1999.
+
+ ---------
+ New text: (Section 18)
+ ---------
+
+ 18. Bibliography
+
+ [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+ Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+ [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP, Computer Communications Review,
+ V. 26 N. 3, July 1996, pp. 5-21.
+
+ [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for
+ Security", RFC 1750, December 1994.
+
+ [RFC1858] Ziemba, G., Reed, D. and Traina P., "Security
+ Considerations for IP Fragment Filtering", RFC 1858,
+ October 1995.
+
+ [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, March 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management
+ Protocol", RFC 2522, March 1999.
+
+
+
+
+Stewart, et al. Informational [Page 30]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+ "TCP Congestion Control with a Misbehaving Receiver", ACM
+ Computer Communication Review, 29(5), October 1999.
+
+2.11.3. Solution Description
+
+ The above text, which adds a new subsection to the Security
+ Considerations section of RFC 2960 [5] makes clear that, to make
+ easier the interaction with firewalls, an INIT chunk must not be
+ bundled in any case with any other chunk that will silently discard
+ the packets that do not follow this rule (this rule is enforced by
+ the packet receiver).
+
+2.12. Shutdown Ambiguity
+
+2.12.1. Description of the Problem
+
+ Currently, there is an ambiguity between the statements in Sections
+ 6.2 and 9.2. Section 6.2 allows the sending of a SHUTDOWN chunk in
+ place of a SACK when the sender is in the process of shutting down,
+ while section 9.2 requires that both a SHUTDOWN chunk and a SACK
+ chunk be sent.
+
+ Along with this ambiguity there is a problem wherein an errant
+ SHUTDOWN receiver may fail to stop accepting user data.
+
+2.12.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 9.2)
+ ---------
+
+ If there are still outstanding DATA chunks left, the SHUTDOWN
+ receiver shall continue to follow normal data transmission procedures
+ defined in Section 6 until all outstanding DATA chunks are
+ acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+ from its SCTP user.
+
+ While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
+ respond to each received packet containing one or more DATA chunk(s)
+ with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer. If
+ it has no more outstanding DATA chunks, the SHUTDOWN receiver shall
+ send a SHUTDOWN ACK and start a T2-shutdown timer of its own,
+ entering the SHUTDOWN-ACK-SENT state. If the timer expires, the
+ endpoint must re-send the SHUTDOWN ACK.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 31]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 9.2)
+ ---------
+
+ If there are still outstanding DATA chunks left, the SHUTDOWN
+ receiver MUST continue to follow normal data transmission procedures
+ defined in Section 6, until all outstanding DATA chunks are
+ acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+ from its SCTP user.
+
+ While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
+ respond to each received packet containing one or more DATA chunks
+ with a SHUTDOWN chunk and restart the T2-shutdown timer. If a
+ SHUTDOWN chunk by itself cannot acknowledge all of the received DATA
+ chunks (i.e., there are TSNs that can be acknowledged that are larger
+ than the cumulative TSN, and thus gaps exist in the TSN sequence), or
+ if duplicate TSNs have been received, then a SACK chunk MUST also be
+ sent.
+
+ The sender of the SHUTDOWN MAY also start an overall guard timer
+ 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+ At the expiration of this timer, the sender SHOULD abort the
+ association by sending an ABORT chunk. If the 'T5-shutdown-guard'
+ timer is used, it SHOULD be set to the recommended value of 5 times
+ 'RTO.Max'.
+
+ If the receiver of the SHUTDOWN has no more outstanding DATA chunks,
+ the SHUTDOWN receiver MUST send a SHUTDOWN ACK and start a
+ T2-shutdown timer of its own, entering the SHUTDOWN-ACK-SENT state.
+ If the timer expires, the endpoint must re-send the SHUTDOWN ACK.
+
+2.12.3. Solution Description
+
+ The above text clarifies the use of a SACK in conjunction with a
+ SHUTDOWN chunk. It also adds a guard timer to the SCTP shutdown
+ sequence to protect against errant receivers of SHUTDOWN chunks.
+
+2.13. Inconsistency in ABORT Processing
+
+2.13.1. Description of the Problem
+
+ It was noted that the wording in Section 8.5.1 did not give proper
+ directions in the use of the 'T bit' with the Verification Tags.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 32]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.13.2. Text changes to the document
+
+ ---------
+ Old text: (Section 8.5.1)
+ ---------
+
+ B) Rules for packet carrying ABORT:
+
+ - The endpoint shall always fill in the Verification Tag field
+ of the outbound packet with the destination endpoint's tag
+ value if it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the
+ endpoint MUST follow the procedure described in Section 8.4.
+
+ - The receiver MUST accept the packet if the Verification Tag
+ matches either its own tag, OR the tag of its peer. Otherwise,
+ the receiver MUST silently discard the packet and take no
+ further action.
+
+ ---------
+ New text: (Section 8.5.1)
+ ---------
+
+ B) Rules for packet carrying ABORT:
+
+ - The endpoint MUST always fill in the Verification Tag field of
+ the outbound packet with the destination endpoint's tag value,
+ if it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the
+ endpoint MUST follow the procedure described in Section 8.4.
+
+ - The receiver of a ABORT MUST accept the packet if the
+ Verification Tag field of the packet matches its own tag OR if
+ it is set to its peer's tag and the T bit is set in the Chunk
+ Flags. Otherwise, the receiver MUST silently discard the
+ packet and take no further action.
+
+2.13.3. Solution Description
+
+ The above text change clarifies that the T bit must be set before an
+ implementation looks for the peer's tag.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 33]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.14. Cwnd Gated by Its Full Use
+
+2.14.1. Description of the Problem
+
+ A problem was found with the current specification of the growth and
+ decay of cwnd. The cwnd should only be increased if it is being
+ fully utilized, and after periods of underutilization, the cwnd
+ should be decreased. In some sections, the current wording is weak
+ and is not clearly defined. Also, the current specification
+ unnecessarily introduces the need for special case code to ensure
+ cwnd degradation. Plus, the cwnd should not be increased during Fast
+ Recovery, since a full cwnd during Fast Recovery does not qualify the
+ cwnd as being fully utilized. Additionally, multiple loss scenarios
+ in a single window may cause the cwnd to grow more rapidly as the
+ number of losses in a window increases [3].
+
+2.14.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.1)
+ ---------
+
+ D) Then, the sender can send out as many new DATA chunks as Rule A
+ and Rule B above allow.
+
+ ---------
+ New text: (Section 6.1)
+ ---------
+
+ D) When the time comes for the sender to transmit new DATA chunks,
+ the protocol parameter Max.Burst SHOULD be used to limit the
+ number of packets sent. The limit MAY be applied by adjusting
+ cwnd as follows:
+
+ if((flightsize + Max.Burst*MTU) < cwnd)
+ cwnd = flightsize + Max.Burst*MTU
+
+ Or it MAY be applied by strictly limiting the number of packets
+ emitted by the output routine.
+
+ E) Then, the sender can send out as many new DATA chunks as Rule A
+ and Rule B allow.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 34]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 7.2.1)
+ ---------
+
+ o When cwnd is less than or equal to ssthresh an SCTP endpoint MUST
+ use the slow start algorithm to increase cwnd (assuming the
+ current congestion window is being fully utilized). If an
+ incoming SACK advances the Cumulative TSN Ack Point, cwnd MUST be
+ increased by at most the lesser of 1) the total size of the
+ previously outstanding DATA chunk(s) acknowledged, and 2) the
+ destination's path MTU. This protects against the ACK-Splitting
+ attack outlined in [SAVAGE99].
+
+ ---------
+ New text: (Section 7.2.1)
+ ---------
+
+ o When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
+ use the slow start algorithm to increase cwnd only if the current
+ congestion window is being fully utilized, an incoming SACK
+ advances the Cumulative TSN Ack Point, and the data sender is not
+ in Fast Recovery. Only when these three conditions are met can
+ the cwnd be increased; otherwise, the cwnd MUST not be increased.
+ If these conditions are met, then cwnd MUST be increased by, at
+ most, the lesser of 1) the total size of the previously
+ outstanding DATA chunk(s) acknowledged, and 2) the destination's
+ path MTU. This upper bound protects against the ACK-Splitting
+ attack outlined in [SAVAGE99].
+
+
+ ---------
+ Old text: (Section 14)
+ ---------
+
+ 14. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.interval - 30 seconds
+
+
+
+Stewart, et al. Informational [Page 35]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 14)
+ ---------
+
+ 14. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ Max.Burst - 4
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.Interval - 30 seconds
+
+2.14.3. Solution Description
+
+ The above changes strengthen the rules and make it much more apparent
+ as to the need to block cwnd growth when the full cwnd is not being
+ utilized. The changes also apply cwnd degradation without
+ introducing the need for complex special case code.
+
+2.15. Window Probes in SCTP
+
+2.15.1. Description of the Problem
+
+ When a receiver clamps its rwnd to 0 to flow control the peer, the
+ specification implies that one must continue to accept data from the
+ remote peer. This is incorrect and needs clarification.
+
+2.15.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.2)
+ ---------
+
+ The SCTP endpoint MUST always acknowledge the receipt of each valid
+ DATA chunk.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 36]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 6.2)
+ ---------
+
+ The SCTP endpoint MUST always acknowledge the reception of each valid
+ DATA chunk when the DATA chunk received is inside its receive window.
+
+ When the receiver's advertised window is 0, the receiver MUST drop
+ any new incoming DATA chunk with a TSN larger than the largest TSN
+ received so far. If the new incoming DATA chunk holds a TSN value
+ less than the largest TSN received so far, then the receiver SHOULD
+ drop the largest TSN held for reordering and accept the new incoming
+ DATA chunk. In either case, if such a DATA chunk is dropped, the
+ receiver MUST immediately send back a SACK with the current receive
+ window showing only DATA chunks received and accepted so far. The
+ dropped DATA chunk(s) MUST NOT be included in the SACK, as they were
+ not accepted. The receiver MUST also have an algorithm for
+ advertising its receive window to avoid receiver silly window
+ syndrome (SWS), as described in RFC 813. The algorithm can be
+ similar to the one described in Section 4.2.3.3 of RFC 1122.
+
+
+ ---------
+ Old text: (Section 6.1)
+ ---------
+
+ A) At any given time, the data sender MUST NOT transmit new data to
+ any destination transport address if its peer's rwnd indicates
+ that the peer has no buffer space (i.e., rwnd is 0, see Section
+ 6.2.1). However, regardless of the value of rwnd (including if it
+ is 0), the data sender can always have one DATA chunk in flight to
+ the receiver if allowed by cwnd (see rule B below). This rule
+ allows the sender to probe for a change in rwnd that the sender
+ missed due to the SACK having been lost in transit from the data
+ receiver to the data sender.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 37]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 6.1)
+ ---------
+
+ A) At any given time, the data sender MUST NOT transmit new data to
+ any destination transport address if its peer's rwnd indicates
+ that the peer has no buffer space (i.e., rwnd is 0; see Section
+ 6.2.1). However, regardless of the value of rwnd (including if it
+ is 0), the data sender can always have one DATA chunk in flight to
+ the receiver if allowed by cwnd (see rule B, below). This rule
+ allows the sender to probe for a change in rwnd that the sender
+ missed due to the SACK's having been lost in transit from the data
+ receiver to the data sender.
+
+ When the receiver's advertised window is zero, this probe is
+ called a zero window probe. Note that a zero window probe
+ SHOULD only be sent when all outstanding DATA chunks have
+ been cumulatively acknowledged and no DATA chunks are in
+ flight. Zero window probing MUST be supported.
+
+ If the sender continues to receive new packets from the receiver
+ while doing zero window probing, the unacknowledged window probes
+ should not increment the error counter for the association or any
+ destination transport address.This is because the receiver MAY
+ keep its window closed for an indefinite time. Refer to
+ Section 6.2 on the receiver behavior when it advertises a zero
+ window. The sender SHOULD send the first zero window probe after
+ 1 RTO when it detects that the receiver has closed its window
+ and SHOULD increase the probe interval exponentially afterwards.
+ Also note that the cwnd SHOULD be adjusted according to
+ Section 7.2.1. Zero window probing does not affect the
+ calculation of cwnd.
+
+ The sender MUST also have an algorithm for sending new DATA chunks
+ to avoid silly window syndrome (SWS) as described in RFC 813. The
+ algorithm can be similar to the one described in Section 4.2.3.4
+ of RFC 1122.
+
+2.15.3. Solution Description
+
+ The above allows a receiver to drop new data that arrives and yet
+ still requires the receiver to send a SACK showing the conditions
+ unchanged (with the possible exception of a new a_rwnd) and the
+ dropped chunk as missing. This will allow the association to
+ continue until the rwnd condition clears.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 38]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.16. Fragmentation and Path MTU Issues
+
+2.16.1. Description of the Problem
+
+ The current wording of the Fragmentation and Reassembly forces an
+ implementation that supports fragmentation to always fragment. This
+ prohibits an implementation from offering its users an option to
+ disable sends that exceed the SCTP fragmentation point.
+
+ The restriction in RFC 2960 [5], Section 6.9, was never meant to
+ restrict an implementations API from this behavior.
+
+2.16.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.1)
+ ---------
+
+ 6.9 Fragmentation and Reassembly
+
+ An endpoint MAY support fragmentation when sending DATA chunks, but
+ MUST support reassembly when receiving DATA chunks. If an endpoint
+ supports fragmentation, it MUST fragment a user message if the size
+ of the user message to be sent causes the outbound SCTP packet size
+ to exceed the current MTU. If an implementation does not support
+ fragmentation of outbound user messages, the endpoint must return an
+ error to its upper layer and not attempt to send the user message.
+
+ IMPLEMENTATION NOTE: In this error case, the Send primitive
+ discussed in Section 10.1 would need to return an error to the upper
+ layer.
+
+ ---------
+ New text: (Section 6.1)
+ ---------
+
+ 6.9. Fragmentation and Reassembly
+
+ An endpoint MAY support fragmentation when sending DATA chunks, but
+ it MUST support reassembly when receiving DATA chunks. If an
+ endpoint supports fragmentation, it MUST fragment a user message if
+ the size of the user message to be sent causes the outbound SCTP
+ packet size to exceed the current MTU. If an implementation does not
+ support fragmentation of outbound user messages, the endpoint MUST
+ return an error to its upper layer and not attempt to send the user
+ message.
+
+
+
+
+
+Stewart, et al. Informational [Page 39]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ Note: If an implementation that supports fragmentation makes
+ available to its upper layer a mechanism to turn off fragmentation it
+ may do so. However, in so doing, it MUST react just like an
+ implementation that does NOT support fragmentation, i.e., it MUST
+ reject sends that exceed the current P-MTU.
+
+ IMPLEMENTATION NOTE: In this error case, the Send primitive
+ discussed in Section 10.1 would need to return an error to the upper
+ layer.
+
+2.16.3. Solution Description
+
+ The above wording will allow an implementation to offer the option of
+ rejecting sends that exceed the P-MTU size even when the
+ implementation supports fragmentation.
+
+2.17. Initial Value of the Cumulative TSN Ack
+
+2.17.1. Description of the Problem
+
+ The current description of the SACK chunk within the RFC does not
+ clearly state the value that would be put within a SACK when no DATA
+ chunk has been received.
+
+2.17.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.4)
+ ---------
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last DATA chunk received in
+ sequence before a gap.
+
+ ---------
+ New text: (Section 3.3.4)
+ ---------
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last DATA chunk received in
+ sequence before a gap. In the case where no DATA chunk has
+ been received, this value is set to the peer's Initial TSN minus
+ one.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 40]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.17.3. Solution Description
+
+ This change clearly states what the initial value will be for a SACK
+ sender.
+
+2.18. Handling of Address Parameters within the INIT or INIT-ACK
+
+2.18.1. Description of the Problem
+
+ The current description on handling address parameters contained
+ within the INIT and INIT-ACK does not fully describe a requirement
+ for their handling.
+
+2.18.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 5.1.2)
+ ---------
+
+ C) If there are only IPv4/IPv6 addresses present in the received INIT
+ or INIT ACK chunk, the receiver shall derive and record all the
+ transport address(es) from the received chunk AND the source IP
+ address that sent the INIT or INIT ACK. The transport address(es)
+ are derived by the combination of SCTP source port (from the
+ common header) and the IP address parameter(s) carried in the INIT
+ or INIT ACK chunk and the source IP address of the IP datagram.
+ The receiver should use only these transport addresses as
+ destination transport addresses when sending subsequent packets to
+ its peer.
+
+ ---------
+ New text: (Section 5.1.2)
+ ---------
+
+ C) If there are only IPv4/IPv6 addresses present in the received INIT
+ or INIT ACK chunk, the receiver MUST derive and record all the
+ transport addresses from the received chunk AND the source IP
+ address that sent the INIT or INIT ACK. The transport addresses
+ are derived by the combination of SCTP source port (from the
+ common header) and the IP address parameter(s) carried in the INIT
+ or INIT ACK chunk and the source IP address of the IP datagram.
+ The receiver should use only these transport addresses as
+ destination transport addresses when sending subsequent packets to
+ its peer.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 41]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ D) An INIT or INIT ACK chunk MUST be treated as belonging
+ to an already established association (or one in the
+ process of being established) if the use of any of the
+ valid address parameters contained within the chunk
+ would identify an existing TCB.
+
+2.18.3. Solution description
+
+ This new text clearly specifies to an implementor the need to look
+ within the INIT or INIT ACK. Any implementation that does not do
+ this may (for example) not be able to recognize an INIT chunk coming
+ from an already established association that adds new addresses (see
+ Section 2.6) or an incoming INIT ACK chunk sent from a source address
+ different from the destination address used to send the INIT chunk.
+
+2.19. Handling of Stream Shortages
+
+2.19.1. Description of the Problem
+
+ The current wording in the RFC places the choice of sending an ABORT
+ upon the SCTP stack when a stream shortage occurs. This decision
+ should really be made by the upper layer, not the SCTP stack.
+
+2.19.2. Text Changes to the Document
+
+ ---------
+ Old text:
+ ---------
+
+ 5.1.1 Handle Stream Parameters
+
+ In the INIT and INIT ACK chunks, the sender of the chunk shall
+ indicate the number of outbound streams (OS) it wishes to have in
+ the association, as well as the maximum inbound streams (MIS) it
+ will accept from the other endpoint.
+
+ After receiving the stream configuration information from the other
+ side, each endpoint shall perform the following check: If the peer's
+ MIS is less than the endpoint's OS, meaning that the peer is
+ incapable of supporting all the outbound streams the endpoint wants
+ to configure, the endpoint MUST either use MIS outbound streams, or
+ abort the association and report to its upper layer the resources
+ shortage at its peer.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 42]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 5.1.2)
+ ---------
+
+ 5.1.1. Handle Stream Parameters
+
+ In the INIT and INIT ACK chunks, the sender of the chunk MUST
+ indicate the number of outbound streams (OS) it wishes to have in
+ the association, as well as the maximum inbound streams (MIS) it will
+ accept from the other endpoint.
+
+ After receiving the stream configuration information from the other
+ side, each endpoint MUST perform the following check: If the peer's
+ MIS is less than the endpoint's OS, meaning that the peer is
+ incapable of supporting all the outbound streams the endpoint wants
+ to configure, the endpoint MUST use MIS outbound streams and MAY
+ report any shortage to the upper layer. The upper layer can then
+ choose to abort the association if the resource shortage
+ is unacceptable.
+
+2.19.3. Solution Description
+
+ The above changes take the decision to ABORT out of the realm of the
+ SCTP stack and place it into the user's hands.
+
+2.20. Indefinite Postponement
+
+2.20.1. Description of the Problem
+
+ The current RFC does not provide any guidance on the assignment of
+ TSN sequence numbers to outbound messages nor reception of these
+ messages. This could lead to a possible indefinite postponement.
+
+2.20.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.1)
+ ---------
+
+ Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+ 1 above the beginning TSN of the current send window.
+
+ 6.2 Acknowledgement on Reception of DATA Chunks
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 43]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 6.1)
+ ---------
+
+ Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+ 1 above the beginning TSN of the current send window.
+
+ The algorithm by which an implementation assigns sequential TSNs to
+ messages on a particular association MUST ensure that no user
+ message that has been accepted by SCTP is indefinitely postponed
+ from being assigned a TSN. Acceptable algorithms for assigning TSNs
+ include
+
+ (a) assigning TSNs in round-robin order over all streams with
+ pending data; and
+
+ (b) preserving the linear order in which the user messages were
+ submitted to the SCTP association.
+
+ When an upper layer requests to read data on an SCTP association,
+ the SCTP receiver SHOULD choose the message with the lowest TSN from
+ among all deliverable messages. In SCTP implementations that allow a
+ user to request data on a specific stream, this operation SHOULD NOT
+ block if data is not available, since this can lead to a deadlock
+ under certain conditions.
+
+ 6.2. Acknowledgement on Receipt of DATA Chunks
+
+2.20.3. Solution Description
+
+ The above wording clarifies how TSNs SHOULD be assigned by the
+ sender.
+
+2.21. User-Initiated Abort of an Association
+
+2.21.1. Description of the Problem
+
+ It is not possible for an upper layer to abort the association and
+ provide the peer with an indication of why the association is
+ aborted.
+
+2.21.2. Text changes to the document
+
+ Some of the changes given here already include changes suggested in
+ Section 2.6 of this document.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 44]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 45]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+ 11 Restart of an Association with New Addresses
+ 12 User-Initiated Abort
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.12 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+ ---------
+ New text: (Note: no old text, new error added in Section 3.3.10)
+ ---------
+
+ 3.3.10.12. User-Initiated Abort (12)
+
+ Cause of error
+ --------------
+
+ This error cause MAY be included in ABORT chunks that are sent
+ because of an upper layer request. The upper layer can specify
+ an Upper Layer Abort Reason that is transported by SCTP
+ transparently and MAY be delivered to the upper layer protocol
+ at the peer.
+
+
+
+
+Stewart, et al. Informational [Page 46]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=12 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Upper Layer Abort Reason /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ---------
+ Old text: (Section 9.1)
+ ---------
+
+ 9.1 Abort of an Association
+
+ When an endpoint decides to abort an existing association, it
+ shall send an ABORT chunk to its peer endpoint. The sender MUST
+ fill in the peer's Verification Tag in the outbound packet and
+ MUST NOT bundle any DATA chunk with the ABORT.
+
+ An endpoint MUST NOT respond to any received packet that contains
+ an ABORT chunk (also see Section 8.4).
+
+ An endpoint receiving an ABORT shall apply the special
+ Verification Tag check rules described in Section 8.5.1.
+
+ After checking the Verification Tag, the receiving endpoint shall
+ remove the association from its record and shall report the
+ termination to its upper layer.
+
+ ---------
+ New text: (Section 9.1)
+ ---------
+
+ 9.1. Abort of an Association
+
+ When an endpoint decides to abort an existing association, it MUST
+ send an ABORT chunk to its peer endpoint. The sender MUST fill in
+ the peer's Verification Tag in the outbound packet and MUST NOT
+ bundle any DATA chunk with the ABORT. If the association is
+ aborted on request of the upper layer, a User-Initiated Abort
+ error cause (see 3.3.10.12) SHOULD be present in the ABORT chunk.
+
+ An endpoint MUST NOT respond to any received packet that contains
+ an ABORT chunk (also see Section 8.4).
+
+ An endpoint receiving an ABORT MUST apply the special Verification
+ Tag check rules described in Section 8.5.1.
+
+ After checking the Verification Tag, the receiving endpoint MUST
+
+
+
+Stewart, et al. Informational [Page 47]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ remove the association from its record and SHOULD report the
+ termination to its upper layer. If a User-Initiated Abort error
+ cause is present in the ABORT chunk, the Upper Layer Abort Reason
+ SHOULD be made available to the upper layer.
+
+ ---------
+ Old text: (Section 10.1)
+ ---------
+
+ D) Abort
+
+ Format: ABORT(association id [, cause code])
+ -> result
+
+ Ungracefully closes an association. Any locally queued user
+ data will be discarded and an ABORT chunk is sent to the peer.
+ A success code will be returned on successful abortion of the
+ association. If attempting to abort the association results
+ in a failure, an error code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ Optional attributes:
+
+ o cause code - reason of the abort to be passed to the peer.
+
+
+ ---------
+ New text: (Section 10.1)
+ ---------
+
+ D) Abort
+
+ Format: ABORT(association id [, Upper Layer Abort Reason])
+ -> result
+
+ Ungracefully closes an association. Any locally queued user
+ data will be discarded, and an ABORT chunk is sent to the peer.
+ A success code will be returned on successful abortion of the
+ association. If attempting to abort the association results
+ in a failure, an error code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - Local handle to the SCTP association.
+
+
+
+
+Stewart, et al. Informational [Page 48]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ Optional attributes:
+
+ o Upper Layer Abort Reason - Reason of the abort to be passed
+ to the peer.
+
+ None.
+
+ ---------
+ Old text: (Section 10.2)
+ ---------
+
+ E) COMMUNICATION LOST notification
+
+ When SCTP loses communication to an endpoint completely (e.g., via
+ Heartbeats) or detects that the endpoint has performed an abort
+ operation, it shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association
+
+ o status - This indicates what type of event has occurred; The
+ status may indicate a failure OR a normal termination
+ event occurred in response to a shutdown or abort
+ request.
+
+ The following may be passed with the notification:
+
+ o data retrieval id - an identification used to retrieve
+ unsent and unacknowledged data.
+
+ o last-acked - the TSN last acked by that peer endpoint;
+
+ o last-sent - the TSN last sent to that peer endpoint;
+
+ ---------
+ New text: (Section 10.2)
+ ---------
+
+ E) COMMUNICATION LOST notification
+
+ When SCTP loses communication to an endpoint completely (e.g., via
+ Heartbeats) or detects that the endpoint has performed an abort
+ operation, it shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - Local handle to the SCTP association.
+
+
+
+Stewart, et al. Informational [Page 49]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ o status - This indicates what type of event has occurred; The
+ status may indicate that a failure OR a normal
+ termination event occurred in response to a shutdown
+ or abort request.
+
+ The following may be passed with the notification:
+
+ o data retrieval id - An identification used to retrieve unsent
+ and unacknowledged data.
+
+ o last-acked - The TSN last acked by that peer endpoint.
+
+ o last-sent - The TSN last sent to that peer endpoint.
+
+ o Upper Layer Abort Reason - The abort reason specified in
+ case of a user-initiated abort.
+
+2.21.3. Solution Description
+
+ The above allows an upper layer to provide its peer with an
+ indication of why the association was aborted. Therefore, an
+ addition error cause was introduced.
+
+2.22. Handling of Invalid Initiate Tag of INIT-ACK
+
+2.22.1. Description of the Problem
+
+ RFC 2960 requires that the receiver of an INIT-ACK with the Initiate
+ Tag set to zero handles this as an error and sends back an ABORT.
+ But the sender of the INIT-ACK normally has no TCB, and thus the
+ ABORT is useless.
+
+2.22.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.3)
+ ---------
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT ACK records the value of the
+ Initiate Tag parameter. This value MUST be placed into
+ the Verification Tag field of every SCTP packet that the
+ INIT ACK receiver transmits within this association.
+
+ The Initiate Tag MUST NOT take the value 0. See Section 5.3.1
+ for more on the selection of the Initiate Tag value.
+
+
+
+
+Stewart, et al. Informational [Page 50]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ If the value of the Initiate Tag in a received INIT ACK chunk
+ is found to be 0, the receiver MUST treat it as an error and
+ close the association by transmitting an ABORT.
+
+ ---------
+ New text: (Section 3.3.3)
+ ---------
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT ACK records the value of the
+ Initiate Tag parameter. This value MUST be placed into
+ the Verification Tag field of every SCTP packet that the
+ INIT ACK receiver transmits within this association.
+
+ The Initiate Tag MUST NOT take the value 0. See Section 5.3.1
+ for more on the selection of the Initiate Tag value.
+
+ If the value of the Initiate Tag in a received INIT ACK
+ chunk is found to be 0, the receiver MUST destroy the
+ association discarding its TCB. The receiver MAY send an
+ ABORT for debugging purpose.
+
+2.22.3. Solution Description
+
+ The new text does not require that the receiver of the invalid INIT-
+ ACK send the ABORT. This behavior is in tune with the error case of
+ invalid stream numbers in the INIT-ACK. However, sending an ABORT
+ for debugging purposes is allowed.
+
+2.23. Sending an ABORT in Response to an INIT
+
+2.23.1. Description of the Problem
+
+ Whenever the receiver of an INIT chunk has to send an ABORT chunk in
+ response, for whatever reason, it is not stated clearly which
+ Verification Tag and value of the T-bit should be used.
+
+2.23.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 8.4)
+ ---------
+
+ 3) If the packet contains an INIT chunk with a Verification Tag
+ set to '0', process it as described in Section 5.1.
+ Otherwise,
+
+
+
+
+Stewart, et al. Informational [Page 51]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 8.4)
+ ---------
+
+ 3) If the packet contains an INIT chunk with a Verification Tag
+ set to '0', process it as described in Section 5.1. If, for
+ whatever reason, the INIT cannot be processed normally and
+ an ABORT has to be sent in response, the Verification Tag
+ of the packet containing the ABORT chunk MUST be the
+ Initiate tag of the received INIT chunk, and the T-Bit of
+ the ABORT chunk has to be set to 0, indicating that
+ a TCB was destroyed. Otherwise,
+
+2.23.3. Solution Description
+
+ The new text stated clearly which value of the Verification Tag and
+ T-bit have to be used.
+
+2.24. Stream Sequence Number (SSN) Initialization
+
+2.24.1. Description of the Problem
+
+ RFC 2960 does not describe the fact that the SSN has to be
+ initialized to 0, as required by RFC 2119.
+
+2.24.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.5)
+ ---------
+
+ The stream sequence number in all the streams shall start from 0
+ when the association is established. Also, when the stream
+ sequence number reaches the value 65535 the next stream sequence
+ number shall be set to 0.
+
+ ---------
+ New text: (Section 6.5)
+ ---------
+
+ The stream sequence number in all the streams MUST start from 0
+ when the association is established. Also, when the stream
+ sequence number reaches the value 65535 the next stream sequence
+ number MUST be set to 0.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 52]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.24.3. Solution Description
+
+ The 'shall' in the text is replaced by a 'MUST' to clearly state the
+ required behavior.
+
+2.25. SACK Packet Format
+
+2.25.1. Description of the Problem
+
+ It is not clear in RFC 2960 whether a SACK must contain the fields
+ Number of Gap Ack Blocks and Number of Duplicate TSNs.
+
+2.25.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.4)
+ ---------
+
+ The SACK MUST contain the Cumulative TSN Ack and
+ Advertised Receiver Window Credit (a_rwnd) parameters.
+
+ ---------
+ New text: (Section 3.3.4)
+ ---------
+
+ The SACK MUST contain the Cumulative TSN Ack,
+ Advertised Receiver Window Credit (a_rwnd), Number
+ of Gap Ack Blocks, and Number of Duplicate TSNs fields.
+
+2.25.3. Solution Description
+
+ The text has been modified. It is now clear that a SACK always
+ contains the fields Number of Gap Ack Blocks and Number of Duplicate
+ TSNs.
+
+2.26. Protocol Violation Error Cause
+
+2.26.1. Description of the Problem
+
+ There are many situations where an SCTP endpoint may detect that its
+ peer violates the protocol. The result of such detection often
+ results in the association being destroyed by the sending of an
+ ABORT. Currently, there are only some error causes that could be
+ used to indicate the reason for the abort, but these do not cover all
+ cases.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 53]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.26.2. Text Changes to the Document
+
+ Some of the changes given here already include changes suggested in
+ Section 2.6 and 2.21 of this document.
+
+ ---------
+ Old text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.10 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 54]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.3.10)
+ ---------
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+ 11 Restart of an Association with New Addresses
+ 12 User Initiated Abort
+ 13 Protocol Violation
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields
+
+ Cause-specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Sections 3.3.10.1 - 3.3.10.13 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 13.3.
+
+ ---------
+ New text: (Note: no old text; new error added in section 3.3.10)
+ ---------
+
+ 3.3.10.13. Protocol Violation (13)
+
+ Cause of error
+ --------------
+
+ This error cause MAY be included in ABORT chunks that are sent
+ because an SCTP endpoint detects a protocol violation of the peer
+ that is not covered by the error causes described in 3.3.10.1 to
+ 3.3.10.12. An implementation MAY provide additional information
+ specifying what kind of protocol violation has been detected.
+
+
+
+Stewart, et al. Informational [Page 55]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=13 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Additional Information /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+2.26.3. Solution Description
+
+ An additional error cause has been defined that can be used by an
+ endpoint to indicate a protocol violation of the peer.
+
+2.27. Reporting of Unrecognized Parameters
+
+2.27.1. Description of the Problem
+
+ It is not stated clearly in RFC 2960 [5] how unrecognized parameters
+ should be reported. Unrecognized parameters in an INIT chunk could
+ be reported in the INIT-ACK chunk or in a separate ERROR chunk, which
+ can get lost. Unrecognized parameters in an INIT-ACK chunk have to
+ be reported in an ERROR-chunk. This can be bundled with the COOKIE-
+ ERROR chunk or sent separately. If it is sent separately and
+ received before the COOKIE-ECHO, it will be handled as an OOTB
+ packet, resulting in sending out an ABORT chunk. Therefore, the
+ association would not be established.
+
+2.27.2. Text Changes to the Document
+
+ Some of the changes given here already include changes suggested in
+ Section 2.2 of this document.
+
+ ---------
+ Old text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type' (in
+ either an ERROR or in the INIT ACK).
+
+
+
+Stewart, et al. Informational [Page 56]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP chunk and discard it; do not process
+ any further parameters within this chunk.
+
+ 01 - Stop processing this SCTP chunk and discard it, do not process
+ any further parameters within this chunk, and report the
+ unrecognized parameter in an 'Unrecognized Parameter Type', as
+ described in 3.2.2.
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type', as
+ described in 3.2.2.
+
+ ---------
+ New text: (Note: no old text; clarification added in Section 3.2)
+ ---------
+
+ 3.2.2. Reporting of Unrecognized Parameters
+
+ If the receiver of an INIT chunk detects unrecognized parameters
+ and has to report them according to Section 3.2.1, it MUST put
+ the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk
+ sent in response to the INIT-chunk. Note that if the receiver
+ of the INIT chunk is NOT going to establish an association (e.g.,
+ due to lack of resources), then no report would be sent back.
+
+ If the receiver of an INIT-ACK chunk detects unrecognized
+ parameters and has to report them according to Section 3.2.1,
+ it SHOULD bundle the ERROR chunk containing the
+ 'Unrecognized Parameter' error cause with the COOKIE-ECHO
+ chunk sent in response to the INIT-ACK chunk. If the
+ receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk
+ with the ERROR chunk, the ERROR chunk MAY be sent separately
+ but not before the COOKIE-ACK has been received.
+
+ Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+ first chunk.
+
+2.27.3. Solution Description
+
+ The procedure of reporting unrecognized parameters has been described
+ clearly.
+
+
+
+
+Stewart, et al. Informational [Page 57]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.28. Handling of IP Address Parameters
+
+2.28.1. Description of the Problem
+
+ It is not stated clearly in RFC 2960 [5] how an SCTP endpoint that
+ supports either IPv4 addresses or IPv6 addresses should respond if
+ IPv4 and IPv6 addresses are presented by the peer in the INIT or
+ INIT-ACK chunk.
+
+2.28.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 5.1.2)
+ ---------
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type,
+ it can abort the initiation process and then attempt a
+ re-initiation by using a 'Supported Address Types' parameter in
+ the new INIT to indicate what types of address it prefers.
+
+ ---------
+ New text: (Section 5.1.2)
+ ---------
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type,
+ it can abort the initiation process and then attempt a re-
+ initiation by using a 'Supported Address Types' parameter in the
+ new INIT to indicate what types of address it prefers.
+
+ IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+ IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT-
+ ACK chunk from its peer, it MUST use all the addresses belonging
+ to the supported address family. The other addresses MAY be
+ ignored. The endpoint SHOULD NOT respond with any kind of error
+ indication.
+
+2.28.3. Solution Description
+
+ The procedure of handling IP address parameters has been described
+ clearly.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 58]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.29. Handling of COOKIE ECHO Chunks When a TCB Exists
+
+2.29.1. Description of the Problem
+
+ The description of the behavior in RFC 2960 [5] when a COOKIE ECHO
+ chunk and a TCB exist could be misunderstood. When a COOKIE ECHO is
+ received, a TCB exists and the local tag and peer's tag match, it is
+ stated that the endpoint should enter the ESTABLISHED state if it has
+ not already done so and send a COOKIE ACK. It was not clear that, in
+ the case the endpoint has already left the ESTABLISHED state again,
+ then it should not go back to established. In case D, the endpoint
+ can only enter state ESTABLISHED from COOKIE-ECHOED because in state
+ CLOSED it has no TCB and in state COOKIE-WAIT it has a TCB but knows
+ nothing about the peer's tag, which is requested to match in this
+ case.
+
+2.29.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 5.2.4)
+ ---------
+ D) When both local and remote tags match the endpoint should
+ always enter the ESTABLISHED state, if it has not already
+ done so. It should stop any init or cookie timers that may
+ be running and send a COOKIE ACK.
+
+ ---------
+ New text: (Section 5.2.4)
+ ---------
+ D) When both local and remote tags match, the endpoint should
+ enter the ESTABLISHED state, if it is in the COOKIE-ECHOED
+ state. It should stop any cookie timer that may
+ be running and send a COOKIE ACK.
+
+2.29.3. Solution Description
+
+ The procedure of handling of COOKIE-ECHO chunks when a TCB exists has
+ been described clearly.
+
+2.30. The Initial Congestion Window Size
+
+2.30.1. Description of the Problem
+
+ RFC 2960 was published with the intention of having the same
+ congestion control properties as TCP. Since the publication of RFC
+ 2960, TCP's initial congestion window size has been increased via RFC
+ 3390. This same update will be needed for SCTP to keep SCTP's
+ congestion control properties equivalent to that of TCP.
+
+
+
+Stewart, et al. Informational [Page 59]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.30.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 7.2.1)
+ ---------
+ o The initial cwnd before DATA transmission or after a
+ sufficiently long idle period MUST be <= 2*MTU.
+
+ ---------
+ New text: (Section 7.2.1)
+ ---------
+ o The initial cwnd before DATA transmission or after a
+ sufficiently long idle period MUST be set to
+ min(4*MTU, max (2*MTU, 4380 bytes)).
+
+ ---------
+ Old text: (Section 7.2.1)
+ ---------
+ o When the endpoint does not transmit data on a given transport
+ address, the cwnd of the transport address should be adjusted
+ to max(cwnd/2, 2*MTU) per RTO.
+
+ ---------
+ New text: (Section 7.2.1)
+ ---------
+ o When the endpoint does not transmit data on a given transport
+ address, the cwnd of the transport address should be adjusted
+ to max(cwnd/2, 4*MTU) per RTO.
+
+ ---------
+ Old text: (Section 7.2.2)
+ ---------
+ o Same as in the slow start, when the sender does not transmit
+ DATA on a given transport address, the cwnd of the transport
+ address should be adjusted to max(cwnd / 2, 2*MTU) per RTO.
+
+ ---------
+ New text: (Section 7.2.2)
+ ---------
+ o Same as in the slow start, when the sender does not transmit
+ DATA on a given transport address, the cwnd of the transport
+ address should be adjusted to max(cwnd / 2, 4*MTU) per RTO.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 60]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 7.2.3)
+ ---------
+
+ 7.2.3. Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), an
+ endpoint should do the following:
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = ssthresh
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform
+ slow start by
+
+ ssthresh = max(cwnd/2, 2*MTU)
+ cwnd = 1*MTU
+
+ ---------
+ New text: (Section 7.2.3)
+ ---------
+
+ 7.2.3 Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), An
+ endpoint should do the following:
+
+ ssthresh = max(cwnd/2, 4*MTU)
+ cwnd = ssthresh
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform
+ slow start by:
+
+ ssthresh = max(cwnd/2, 4*MTU)
+ cwnd = 1*MTU
+
+2.30.3. Solution Description
+
+ The change to SCTP's initial congestion window will allow it to
+ continue to maintain the same congestion control properties as TCP.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 61]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.31. Stream Sequence Numbers in Figures
+
+2.31.1. Description of the Problem
+
+ In Section 2.24 of this document, it is clarified that the SSN are
+ initialized with 0. Two figures in RFC 2960 [5] illustrate that they
+ start with 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 62]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.31.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 7.2.1)
+ ---------
+
+ Endpoint A Endpoint Z
+ {app sets association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A
+ & other info] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z)
+ /-- INIT ACK [Veri Tag=Tag_A,
+ / I-Tag=Tag_Z,
+ (Cancel T1-init timer) <-----/ Cookie_Z, & other info]
+ (destroy temp TCB)
+ COOKIE ECHO [Cookie_Z] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED
+ state)
+ /---- COOKIE-ACK
+ /
+ (Cancel T1-init timer, <-----/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=1 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /----- SACK [TSN Ack=init
+ / TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+ ...
+ {app sends 2 messages;strm 0}
+ /---- DATA
+ / [TSN=init TSN_Z
+ <--/ Strm=0,Seq=1 & user data 1]
+ SACK [TSN Ack=init TSN_Z, / ---- DATA
+ Block=0] --------\ / [TSN=init TSN_Z +1,
+ \/ Strm=0,Seq=2 & user data 2]
+ <------/\
+ \
+ \------>
+
+ Figure 4: INITiation Example
+
+
+
+
+
+Stewart, et al. Informational [Page 63]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 7.2.1)
+ ---------
+
+
+ Endpoint A Endpoint Z
+ {app sets association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A
+ & other info] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z)
+ /-- INIT ACK [Veri Tag=Tag_A,
+ / I-Tag=Tag_Z,
+ (Cancel T1-init timer) <------/ Cookie_Z, & other info]
+ (destroy temp TCB)
+ COOKIE ECHO [Cookie_Z] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED
+ state)
+ /---- COOKIE-ACK
+ /
+ (Cancel T1-init timer, <-----/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=0 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /----- SACK [TSN Ack=init
+ / TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+ ...
+ {app sends 2 messages;strm 0}
+ /---- DATA
+ / [TSN=init TSN_Z
+ <--/ Strm=0,Seq=0 & user data 1]
+ SACK [TSN Ack=init TSN_Z, /---- DATA
+ Block=0] --------\ / [TSN=init TSN_Z +1,
+ \/ Strm=0,Seq=1 & user data 2]
+ <------/\
+ \
+ \------>
+
+ Figure 4: INITiation Example
+
+
+
+
+
+
+Stewart, et al. Informational [Page 64]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 5.2.4.1)
+ ---------
+
+ Endpoint A Endpoint Z
+ <------------ Association is established---------------------->
+ Tag=Tag_A Tag=Tag_Z
+ <------------------------------------------------------------->
+ {A crashes and restarts}
+ {app sets up a association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A'
+ & other info] --------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (find a existing TCB
+ compose temp TCB and Cookie_Z
+ with Tie-Tags to previous
+ association)
+ /--- INIT ACK [Veri Tag=Tag_A',
+ / I-Tag=Tag_Z',
+ (Cancel T1-init timer) <------/ Cookie_Z[TieTags=
+ Tag_A,Tag_Z
+ & other info]
+ (destroy temp TCB,leave original
+ in place)
+ COOKIE ECHO [Veri=Tag_Z',
+ Cookie_Z
+ Tie=Tag_A,
+ Tag_Z]----------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (Find existing association,
+ Tie-Tags match old tags,
+ Tags do not match i.e.,
+ case X X M M above,
+ Announce Restart to ULP
+ and reset association).
+ /---- COOKIE-ACK
+ (Cancel T1-init timer, <------/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=1 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /--- SACK [TSN Ack=init TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+
+ Figure 5: A Restart Example
+
+
+
+Stewart, et al. Informational [Page 65]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 5.2.4.1)
+ ---------
+
+ Endpoint A Endpoint Z
+ <-------------- Association is established---------------------->
+ Tag=Tag_A Tag=Tag_Z
+ <--------------------------------------------------------------->
+ {A crashes and restarts}
+ {app sets up a association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A'
+ & other info] --------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (find a existing TCB
+ compose temp TCB and Cookie_Z
+ with Tie-Tags to previous
+ association)
+ /--- INIT ACK [Veri Tag=Tag_A',
+ / I-Tag=Tag_Z',
+ (Cancel T1-init timer) <------/ Cookie_Z[TieTags=
+ Tag_A,Tag_Z
+ & other info]
+ (destroy temp TCB,leave original
+ in place)
+ COOKIE ECHO [Veri=Tag_Z',
+ Cookie_Z
+ Tie=Tag_A,
+ Tag_Z]----------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (Find existing association,
+ Tie-Tags match old tags,
+ Tags do not match i.e.,
+ case X X M M above,
+ Announce Restart to ULP
+ and reset association).
+ /---- COOKIE-ACK
+ (Cancel T1-init timer, <------/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=0 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /--- SACK [TSN Ack=init TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+
+ Figure 5: A Restart Example
+
+
+
+Stewart, et al. Informational [Page 66]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.31.3. Solution description
+
+ Figure 4 and 5 were changed so that the SSN starts with 0 instead of
+ 1.
+
+2.32. Unrecognized Parameters
+
+2.32.1. Description of the Problem
+
+ The RFC does not state clearly in Section 3.3.3.1 whether one or
+ multiple unrecognized parameters are included in the 'Unrecognized
+ Parameter' parameter.
+
+2.32.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.3)
+ ---------
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ State Cookie Mandatory 7
+ IPv4 Address (Note 1) Optional 5
+ IPv6 Address (Note 1) Optional 6
+ Unrecognized Parameters Optional 8
+ Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
+ Host Name Address (Note 3) Optional 11
+
+ ---------
+ New text: (Section 3.3.3)
+ ---------
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ State Cookie Mandatory 7
+ IPv4 Address (Note 1) Optional 5
+ IPv6 Address (Note 1) Optional 6
+ Unrecognized Parameter Optional 8
+ Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
+ Host Name Address (Note 3) Optional 11
+
+
+ ---------
+ Old text: (Section 3.3.3.1)
+ ---------
+ Unrecognized Parameters:
+
+ Parameter Type Value: 8
+
+ Parameter Length: Variable Size.
+
+
+
+Stewart, et al. Informational [Page 67]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ Parameter Value:
+ This parameter is returned to the originator of the INIT
+ chunk when the INIT contains an unrecognized parameter
+ which has a value that indicates that it should be reported
+ to the sender. This parameter value field will contain
+ unrecognized parameters copied from the INIT chunk complete
+ with Parameter Type, Length and Value fields.
+
+ ---------
+ New text: (Section 3.3.3.1)
+ ---------
+ Unrecognized Parameter:
+
+ Parameter Type Value: 8
+
+ Parameter Length: Variable Size.
+
+ Parameter Value:
+
+ This parameter is returned to the originator of the INIT
+ chunk when the INIT contains an unrecognized parameter
+ that has a value that indicates that it should be reported
+ to the sender. This parameter value field will contain the
+ unrecognized parameter copied from the INIT chunk complete
+ with Parameter Type, Length, and Value fields.
+
+2.32.3. Solution Description
+
+ The new text states clearly that only one unrecognized parameter is
+ reported per parameter.
+
+2.33. Handling of Unrecognized Parameters
+
+2.33.1. Description of the Problem
+
+ It is not stated clearly in RFC 2960 [5] how unrecognized parameters
+ should be handled. The problem comes up when an INIT contains an
+ unrecognized parameter with highest bits 00. It was not clear
+ whether an INIT-ACK should be sent.
+
+2.33.2. Text Changes to the Document
+
+ Some of the changes given here already include changes suggested in
+ Section 2.27 of this document.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 68]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type' (in
+ either an ERROR or in the INIT ACK).
+
+ ---------
+ New text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this parameter; do not process
+ any further parameters within this chunk.
+
+ 01 - Stop processing this parameter, do not process
+ any further parameters within this chunk, and report the
+ unrecognized parameter in an 'Unrecognized Parameter Type', as
+ described in 3.2.2.
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type', as
+ described in 3.2.2.
+
+
+ ---------
+ New text: (Note: no old text; clarification added in section 3.2)
+ ---------
+
+ 3.2.2. Reporting of Unrecognized Parameters
+
+ If the receiver of an INIT chunk detects unrecognized parameters and
+ has to report them according to Section 3.2.1, it MUST put the
+ 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk sent in
+ response to the INIT-chunk. Note that if the receiver of the INIT
+ chunk is NOT going to establish an association (e.g., due to lack of
+
+
+
+Stewart, et al. Informational [Page 69]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ resources), an 'Unrecognized Parameter' would NOT be included with
+ any ABORT being sent to the sender of the INIT.
+
+ If the receiver of an INIT-ACK chunk detects unrecognized parameters
+ and has to report them according to Section 3.2.1, it SHOULD bundle
+ the ERROR chunk containing the 'Unrecognized Parameter' error cause
+ with the COOKIE-ECHO chunk sent in response to the INIT-ACK chunk.
+ If the receiver of the INIT-ACK cannot bundle the COOKIE-ECHO chunk
+ with the ERROR chunk, the ERROR chunk MAY be sent separately but not
+ before the COOKIE-ACK has been received.
+
+ Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+ first chunk.
+
+2.33.3. Solution Description
+
+ The procedure of handling unrecognized parameters has been described
+ clearly.
+
+2.34. Tie Tags
+
+2.34.1. Description of the Problem
+
+ RFC 2960 requires that Tie-Tags be included in the COOKIE. The
+ cookie may not be encrypted. An attacker could discover the value of
+ the Verification Tags by analyzing cookies received after sending an
+ INIT.
+
+2.34.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 1.4)
+ ---------
+ o Tie-Tags: Verification Tags from a previous association. These
+ Tags are used within a State Cookie so that the newly
+ restarting association can be linked to the original
+ association within the endpoint that did not restart.
+
+ ---------
+ New text: (Section 1.4)
+ ---------
+
+ o Tie-Tags: Two 32-bit random numbers that together make a 64-
+ bit nonce. These Tags are used within a State Cookie and TCB
+ so that a newly restarting association can be linked to the
+ original association within the endpoint that did not restart
+ and yet not reveal the true Verification Tags of an existing
+ association.
+
+
+
+Stewart, et al. Informational [Page 70]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 5.2.1)
+ ---------
+
+ For an endpoint that is in the COOKIE-ECHOED state it MUST
+ populate its Tie-Tags with the Tag information of itself and
+ its peer (see Section 5.2.2 for a description of the Tie-Tags).
+
+ ---------
+ New text: (Section 5.2.1)
+ ---------
+ For an endpoint that is in the COOKIE-ECHOED state it MUST
+ populate its Tie-Tags within both the association TCB and
+ inside the State Cookie (see section 5.2.2 for a description
+ of the Tie-Tags).
+
+
+ ---------
+ Old text: (Section 5.2.2)
+ ---------
+ Unless otherwise stated, upon reception of an unexpected INIT for
+ this association, the endpoint shall generate an INIT ACK with a
+ State Cookie. In the outbound INIT ACK the endpoint MUST copy its
+ current Verification Tag and peer's Verification Tag into a
+ reserved place within the state cookie. We shall refer to these
+ locations as the Peer's-Tie-Tag and the Local-Tie-Tag. The
+ outbound SCTP packet containing this INIT ACK MUST carry a
+ Verification Tag value equal to the Initiation Tag found in the
+ unexpected INIT. And the INIT ACK MUST contain a new Initiation
+ Tag (randomly generated see Section 5.3.1). Other parameters
+ for the endpoint SHOULD be copied from the existing parameters
+ of the association (e.g., number of outbound streams) into the
+ INIT ACK and cookie.
+
+ ---------
+ New text: (Section 5.2.2)
+ ---------
+
+ Unless otherwise stated, upon receipt of an unexpected INIT for
+ this association, the endpoint MUST generate an INIT ACK with a
+ State Cookie. In the outbound INIT ACK, the endpoint MUST copy
+ its current Tie-Tags to a reserved place within the State Cookie
+ and the association's TCB. We shall refer to these locations
+ inside the cookie as the Peer's-Tie-Tag and the Local-Tie-Tag. We
+ will refer to the copy within an association's TCB as the Local
+ Tag and Peer's Tag. The outbound SCTP packet containing this INIT
+ ACK MUST carry a Verification Tag value equal to the Initiation
+ Tag found in the unexpected INIT. And the INIT ACK MUST contain a
+
+
+
+Stewart, et al. Informational [Page 71]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ new Initiation Tag (randomly generated; see Section 5.3.1). Other
+ parameters for the endpoint SHOULD be copied from the existing
+ parameters of the association (e.g., number of outbound streams)
+ into the INIT ACK and cookie.
+
+2.34.3. Solution Description
+
+ The solution to this problem is not to use the real Verification Tags
+ within the State Cookie as tie-tags. Instead, two 32-bit random
+ numbers are created to form one 64-bit nonce and stored both in the
+ State Cookie and the existing association TCB. This prevents
+ exposing the Verification Tags inadvertently.
+
+2.35. Port Number Verification in the COOKIE-ECHO
+
+2.35.1. Description of the Problem
+
+ The State Cookie sent by a listening SCTP endpoint may not contain
+ the original port numbers or the local Verification Tag. It is then
+ possible that the endpoint, on receipt of the COOKIE-ECHO, will not
+ be able to verify that these values match the original values found
+ in the INIT and INIT-ACK that began the association setup.
+
+2.35.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 5.1.5)
+ ---------
+ 3) Compare the creation timestamp in the State Cookie to the
+ current local time. If the elapsed time is longer than the
+ lifespan carried in the State Cookie, then the packet,
+ including the COOKIE ECHO and any attached DATA chunks,
+ SHOULD be discarded and the endpoint MUST transmit an ERROR
+ chunk with a "Stale Cookie" error cause to the peer endpoint,
+
+ 4) If the State Cookie is valid, create an association to the
+ sender of the COOKIE ECHO chunk with the information in the
+ TCB data carried in the COOKIE ECHO, and enter the
+ ESTABLISHED state,
+
+ 5) Send a COOKIE ACK chunk to the peer acknowledging reception
+ of the COOKIE ECHO. The COOKIE ACK MAY be bundled with an
+ outbound DATA chunk or SACK chunk; however, the COOKIE ACK
+ MUST be the first chunk in the SCTP packet.
+
+ 6) Immediately acknowledge any DATA chunk bundled with the COOKIE
+ ECHO with a SACK (subsequent DATA chunk acknowledgement should
+ follow the rules defined in Section 6.2). As mentioned in step
+
+
+
+Stewart, et al. Informational [Page 72]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 5), if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+ MUST appear first in the SCTP packet.
+
+ ---------
+ New text: (Section 5.1.5)
+ ---------
+
+ 3) Compare the port numbers and the Verification Tag contained
+ within the COOKIE ECHO chunk to the actual port numbers and the
+ Verification Tag within the SCTP common header of the received
+ packet. If these values do not match, the packet MUST be
+ silently discarded.
+
+ 4) Compare the creation timestamp in the State Cookie to the
+ current local time. If the elapsed time is longer than the
+ lifespan carried in the State Cookie, then the packet,
+ including the COOKIE ECHO and any attached DATA chunks,
+ SHOULD be discarded, and the endpoint MUST transmit an
+ ERROR chunk with a "Stale Cookie" error cause to the peer
+ endpoint.
+
+ 5) If the State Cookie is valid, create an association to the
+ sender of the COOKIE ECHO chunk with the information in the
+ TCB data carried in the COOKIE ECHO and enter the
+ ESTABLISHED state.
+
+ 6) Send a COOKIE ACK chunk to the peer acknowledging receipt of
+ the COOKIE ECHO. The COOKIE ACK MAY be bundled with an
+ outbound DATA chunk or SACK chunk; however, the COOKIE ACK
+ MUST be the first chunk in the SCTP packet.
+
+ 7) Immediately acknowledge any DATA chunk bundled with the COOKIE
+ ECHO with a SACK (subsequent DATA chunk acknowledgement should
+ follow the rules defined in Section 6.2). As mentioned in step
+ 5, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+ MUST appear first in the SCTP packet.
+
+2.35.3. Solution Description
+
+ By including both port numbers and the local Verification Tag within
+ the State Cookie and verifying these during COOKIE-ECHO processing,
+ this issue is resolved.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 73]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.36. Path Initialization
+
+2.36.1. Description of the Problem
+
+ When an association enters the ESTABLISHED state, the endpoint has no
+ verification that all of the addresses presented by the peer do in
+ fact belong to the peer. This could cause various forms of denial of
+ service attacks.
+
+2.36.2. Text Changes to the Document
+
+ ---------
+ Old text: None
+ ---------
+
+ ---------
+ New text: (Section 5.4)
+ ---------
+ 5.4. Path Verification
+
+ During association establishment, the two peers exchange a list of
+ addresses. In the predominant case, these lists accurately represent
+ the addresses owned by each peer. However, it is possible that a
+ misbehaving peer may supply addresses that it does not own. To
+ prevent this, the following rules are applied to all addresses of the
+ new association:
+
+ 1) Any address passed to the sender of the INIT by its upper layer is
+ automatically considered to be CONFIRMED.
+
+ 2) For the receiver of the COOKIE-ECHO the only CONFIRMED address is
+ the one that the INIT-ACK was sent to.
+
+ 3) All other addresses not covered by rules 1 and 2 are considered
+ UNCONFIRMED and are subject to probing for verification.
+
+ To probe an address for verification, an endpoint will send
+ HEARTBEATs including a 64-bit random nonce and a path indicator (to
+ identify the address that the HEARTBEAT is sent to) within the
+ HEARTBEAT parameter.
+
+ Upon receipt of the HEARTBEAT-ACK, a verification is made that the
+ nonce included in the HEARTBEAT parameter is the one sent to the
+ address indicated inside the HEARTBEAT parameter. When this match
+ occurs, the address that the original HEARTBEAT was sent to is now
+ considered CONFIRMED and available for normal data transfer.
+
+
+
+
+
+Stewart, et al. Informational [Page 74]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ These probing procedures are started when an association moves to the
+ ESTABLISHED state and are ended when all paths are confirmed.
+
+ Each RTO a probe may be sent on an active UNCONFIRMED path in an
+ attempt to move it to the CONFIRMED state. If during this probing
+ the path becomes inactive, this rate is lowered to the normal
+ HEARTBEAT rate. At the expiration of the RTO timer, the error
+ counter of any path that was probed but not CONFIRMED is incremented
+ by one and subjected to path failure detection, as defined in section
+ 8.2. When probing UNCONFIRMED addresses, however, the association
+ overall error count is NOT incremented.
+
+ The number of HEARTBEATS sent at each RTO SHOULD be limited by the
+ HB.Max.Burst parameter. It is an implementation decision as to how
+ to distribute HEARTBEATS to the peer's addresses for path
+ verification.
+
+ Whenever a path is confirmed, an indication MAY be given to the upper
+ layer.
+
+ An endpoint MUST NOT send any chunks to an UNCONFIRMED address, with
+ the following exceptions:
+
+ - A HEARTBEAT including a nonce MAY be sent to an UNCONFIRMED
+ address.
+
+ - A HEARTBEAT-ACK MAY be sent to an UNCONFIRMED address.
+
+ - A COOKIE-ACK MAY be sent to an UNCONFIRMED address, but it MUST be
+ bundled with a HEARTBEAT including a nonce. An implementation that
+ does NOT support bundling MUST NOT send a COOKIE-ACK to an
+ UNCONFIRMED address.
+
+ - A COOKE-ECHO MAY be sent to an UNCONFIRMED address, but it MUST be
+ bundled with a HEARTBEAT including a nonce, and the packet MUST NOT
+ exceed the path MTU. If the implementation does NOT support
+ bundling or if the bundled COOKIE-ECHO plus HEARTBEAT (including
+ nonce) would exceed the path MTU, then the implementation MUST NOT
+ send a COOKIE-ECHO to an UNCONFIRMED address.
+
+ ---------
+ Old text: (Section 14)
+ ---------
+
+ 14. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+
+
+
+Stewart, et al. Informational [Page 75]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.interval - 30 seconds
+
+ ---------
+ New text: (Section 14)
+ ---------
+
+ 14. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ Max.Burst - 4
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.Interval - 30 seconds
+ HB.Max.Burst - 1
+
+2.36.3. Solution Description
+
+ By properly setting up initial path state and accelerated probing via
+ HEARTBEAT's, a new association can verify that all addresses
+ presented by a peer belong to that peer.
+
+2.37. ICMP Handling Procedures
+
+2.37.1. Description of the Problem
+
+ RFC 2960 does not describe how ICMP messages should be processed by
+ an SCTP endpoint.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 76]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.37.2. Text Changes to the Document
+
+ --------
+ Old text: None
+ --------
+
+ ---------
+ New text
+ ---------
+
+ 11.5. Protection of Non-SCTP Capable Hosts.
+
+ To provide a non-SCTP capable host with the same level of protection
+ against attacks as for SCTP-capable ones, all SCTP stacks MUST
+ implement the ICMP handling described in Appendix C.
+
+ When an SCTP stack receives a packet containing multiple control or
+ DATA chunks and the processing of the packet requires the sending of
+ multiple chunks in response, the sender of the response chunk(s) MUST
+ NOT send more than one packet. If bundling is supported, multiple
+ response chunks that fit into a single packet MAY be bundled together
+ into one single response packet. If bundling is not supported, then
+ the sender MUST NOT send more than one response chunk and MUST
+ discard all other responses. Note that this rule does NOT apply to a
+ SACK chunk, since a SACK chunk is, in itself, a response to DATA and
+ a SACK does not require a response of more DATA.
+
+ An SCTP implementation SHOULD abort the association if it receives a
+ SACK acknowledging a TSN that has not been sent.
+
+ An SCTP implementation that receives an INIT that would require a
+ large packet in response, due to the inclusion of multiple ERROR
+ parameters, MAY (at its discretion) elect to omit some or all of the
+ ERROR parameters to reduce the size of the INIT-ACK. Due to a
+ combination of the size of the COOKIE parameter and the number of
+ addresses a receiver of an INIT may be indicating to a peer, it is
+ always possible that the INIT-ACK will be larger than the original
+ INIT. An SCTP implementation SHOULD attempt to make the INIT-ACK as
+ small as possible to reduce the possibility of byte amplification
+ attacks.
+
+ ---------
+ Old text: None
+ ---------
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 77]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Appendix C)
+ ---------
+
+ Appendix C ICMP Handling
+
+ Whenever an ICMP message is received by an SCTP endpoint the
+ following procedures MUST be followed to ensure proper utilization of
+ the information being provided by layer 3.
+
+ ICMP1) An implementation MAY ignore all ICMPv4 messages where the
+ type field is not set to "Destination Unreachable".
+
+ ICMP2) An implementation MAY ignore all ICMPv6 messages where the
+ type field is not "Destination Unreachable, "Parameter
+ Problem" or "Packet Too Big".
+
+ ICMP3) An implementation MAY ignore any ICMPv4 messages where the
+ code does not indicate "Protocol Unreachable" or
+ "Fragmentation Needed".
+
+ ICMP4) An implementation MAY ignore all ICMPv6 messages of type
+ "Parameter Problem" if the code is not "Unrecognized next
+ header type encountered".
+
+ ICMP5) An implementation MUST use the payload of the ICMP message (V4
+ or V6) to locate the association that sent the message that
+ ICMP is responding to. If the association cannot be found, an
+ implementation SHOULD ignore the ICMP message.
+
+ ICMP6) An implementation MUST validate that the Verification Tag
+ contained in the ICMP message matches the verification tag of
+ the peer. If the Verification Tag is not 0 and does NOT
+ match, discard the ICMP message. If it is 0 and the ICMP
+ message contains enough bytes to verify that the chunk type is
+ an INIT chunk and that the initiate tag matches the tag of the
+ peer, continue with ICMP7. If the ICMP message is too short
+ or the chunk type or the initiate tag does not match, silently
+ discard the packet.
+
+ ICMP7) If the ICMP message is either a V6 "Packet Too Big" or a V4
+ "Fragmentation Needed", an implementation MAY process this
+ information as defined for PATH MTU discovery.
+
+ ICMP8) If the ICMP code is a "Unrecognized next header type
+ encountered" or a "Protocol Unreachable", an implementation
+ MUST treat this message as an abort with the T bit set if it
+ does not contain an INIT chunk. If it does contain an INIT
+
+
+
+Stewart, et al. Informational [Page 78]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ chunk and the association is in COOKIE-WAIT state, handle the
+ ICMP message like an ABORT.
+
+ ICMP9) If the ICMPv6 code is "Destination Unreachable", the
+ implementation MAY mark the destination into the unreachable
+ state or alternatively increment the path error counter.
+
+ Note that these procedures differ from RFC 1122 [1] and from its
+ requirements for processing of port-unreachable messages and the
+ requirements that an implementation MUST abort associations in
+ response to a "protocol unreachable" message. Port unreachable
+ messages are not processed, since an implementation will send an
+ ABORT, not a port unreachable. The stricter handling of the
+ "protocol unreachable" message is due to security concerns for hosts
+ that do NOT support SCTP.
+
+2.37.3. Solution Description
+
+ The new appendix now describes proper handling of ICMP messages in
+ conjunction with SCTP.
+
+2.38. Checksum
+
+2.38.1. Description of the problem
+
+ RFC 3309 [6] changes the SCTP checksum due to weaknesses in the
+ original Adler 32 checksum for small messages. This document, being
+ used as a guide for a cut and paste replacement to update RFC 2960,
+ thus also needs to incorporate the checksum changes. The idea is
+ that one could apply all changes found in this guide to a copy of RFC
+ 2960 and have a "new" document that has ALL changes (including RFC
+ 3309).
+
+2.38.2. Text Changes to the Document
+
+ ---------
+ Old text:
+ ---------
+
+ 6.8 Adler-32 Checksum Calculation
+
+ When sending an SCTP packet, the endpoint MUST strengthen the data
+ integrity of the transmission by including the Adler-32 checksum
+ value calculated on the packet, as described below.
+
+ After the packet is constructed (containing the SCTP common header
+ and one or more control or DATA chunks), the transmitter shall:
+
+
+
+
+Stewart, et al. Informational [Page 79]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ 1) Fill in the proper Verification Tag in the SCTP common header
+ and initialize the checksum field to 0's.
+
+ 2) Calculate the Adler-32 checksum of the whole packet, including
+ the SCTP common header and all the chunks. Refer to
+ appendix B for details of the Adler-32 algorithm. And,
+
+ 3) Put the resultant value into the checksum field in the common
+ header, and leave the rest of the bits unchanged.
+
+ When an SCTP packet is received, the receiver MUST first check the
+ Adler-32 checksum:
+
+ 1) Store the received Adler-32 checksum value aside,
+
+ 2) Replace the 32 bits of the checksum field in the received SCTP
+ packet with all '0's and calculate an Adler-32 checksum value
+ of the whole received packet. And,
+
+ 3) Verify that the calculated Adler-32 checksum is the same as the
+ received Adler-32 checksum. If not, the receiver MUST treat
+ the packet as an invalid SCTP packet.
+
+ The default procedure for handling invalid SCTP packets is to
+ silently discard them.
+
+ ---------
+ New text:
+ ---------
+
+ 6.8 CRC-32c Checksum Calculation
+
+ When sending an SCTP packet, the endpoint MUST strengthen the data
+ integrity of the transmission by including the CRC32c checksum
+ value calculated on the packet, as described below.
+
+ After the packet is constructed (containing the SCTP common header
+ and one or more control or DATA chunks), the transmitter MUST
+
+ 1) fill in the proper Verification Tag in the SCTP common header
+ and initialize the checksum field to '0's,
+
+ 2) calculate the CRC32c checksum of the whole packet, including
+ the SCTP common header and all the chunks (refer to
+ appendix B for details of the CRC32c algorithm); and
+
+ 3) put the resultant value into the checksum field in the common
+ header, and leave the rest of the bits unchanged.
+
+
+
+Stewart, et al. Informational [Page 80]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ When an SCTP packet is received, the receiver MUST first check the
+ CRC32c checksum as follows:
+
+ 1) Store the received CRC32c checksum value aside.
+
+ 2) Replace the 32 bits of the checksum field in the received SCTP
+ packet with all '0's and calculate a CRC32c checksum value of
+ the whole received packet.
+
+ 3) Verify that the calculated CRC32c checksum is the same as the
+ received CRC32c checksum. If it is not, the receiver MUST
+ treat the packet as an invalid SCTP packet.
+
+ The default procedure for handling invalid SCTP packets is to
+ silently discard them.
+
+ Any hardware implementation SHOULD be done in a way that is
+ verifiable by the software.
+
+
+ ---------
+ Old text:
+ ---------
+
+ Appendix B Alder 32 bit checksum calculation
+
+ The Adler-32 checksum calculation given in this appendix is
+ copied from [RFC1950].
+
+ Adler-32 is composed of two sums accumulated per byte: s1 is the
+ sum of all bytes, s2 is the sum of all s1 values. Both sums are
+ done modulo 65521. s1 is initialized to 1, s2 to zero. The
+ Adler-32 checksum is stored as s2*65536 + s1 in network byte
+ order.
+
+ The following C code computes the Adler-32 checksum of a data
+ buffer. It is written for clarity, not for speed. The sample
+ code is in the ANSI C programming language. Non C users may
+ find it easier to read with these hints:
+
+ & Bitwise AND operator.
+ >> Bitwise right shift operator. When applied to an
+ unsigned quantity, as here, right shift inserts zero bit(s)
+ at the left.
+ << Bitwise left shift operator. Left shift inserts zero
+ bit(s) at the right.
+ ++ "n++" increments the variable n.
+ % modulo operator: a % b is the remainder of a divided by b.
+
+
+
+Stewart, et al. Informational [Page 81]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ #define BASE 65521 /* largest prime smaller than 65536 */
+ /*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1]
+ and return the updated checksum. The Adler-32 checksum should
+ be initialized to 1.
+
+ Usage example:
+
+ unsigned long adler = 1L;
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = update_adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+ */
+ unsigned long update_adler32(unsigned long adler,
+ unsigned char *buf, int len)
+ {
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int n;
+
+ for (n = 0; n < len; n++) {
+ s1 = (s1 + buf[n]) % BASE;
+ s2 = (s2 + s1) % BASE;
+ }
+ return (s2 << 16) + s1;
+ }
+
+ /* Return the adler32 of the bytes buf[0..len-1] */
+ unsigned long adler32(unsigned char *buf, int len)
+ {
+ return update_adler32(1L, buf, len);
+ }
+
+ ---------
+ New text:
+ ---------
+
+ Appendix B CRC32c Checksum Calculation
+
+ We define a 'reflected value' as one that is the opposite of the
+ normal bit order of the machine. The 32-bit CRC is calculated as
+ described for CRC-32c and uses the polynomial code 0x11EDC6F41
+ (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+ +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0.
+ The CRC is computed using a procedure similar to ETHERNET CRC
+ [ITU32], modified to reflect transport level usage.
+
+
+
+Stewart, et al. Informational [Page 82]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ CRC computation uses polynomial division. A message
+ bit-string M is transformed to a polynomial, M(X), and the CRC
+ is calculated from M(X) using polynomial arithmetic [PETERSON 72].
+
+ When CRCs are used at the link layer, the polynomial is derived
+ from on-the-wire bit ordering: the first bit 'on the wire' is the
+ high-order coefficient. Since SCTP is a transport-level protocol,
+ it cannot know the actual serial-media bit ordering. Moreover,
+ different links in the path between SCTP endpoints may use
+ different link-level bit orders.
+
+ A convention must therefore be established for mapping SCTP
+ transport messages to polynomials for purposes of CRC computation.
+ The bit-ordering for mapping SCTP messages to polynomials is that
+ bytes are taken most-significant first; but within each byte, bits
+ are taken least-significant first. The first byte of the message
+ provides the eight highest coefficients. Within each byte,
+ the least-significant SCTP bit gives the most significant
+ polynomial coefficient within that byte, and the most-significant
+ SCTP bit is the least significant polynomial coefficient in that
+ byte. (This bit ordering is sometimes called 'mirrored' or
+ 'reflected' [WILLIAMS93].) CRC polynomials are to be transformed
+ back into SCTP transport-level byte values, using a consistent
+ mapping.
+
+ The SCTP transport-level CRC value should be calculated as
+ follows:
+
+ - CRC input data are assigned to a byte stream, numbered from
+ 0 to N-1.
+
+ - The transport-level byte-stream is mapped to a polynomial
+ value. An N-byte PDU with j bytes numbered 0 to N-1 is
+ considered as coefficients of a polynomial M(x) of order
+ 8N-1, with bit 0 of byte j being coefficient x^(8(N-j)-8),
+ and bit 7 of byte j being coefficient x^(8(N-j)-1).
+
+ - The CRC remainder register is initialized with all 1s and
+ the CRC is computed with an algorithm that simultaneously
+ multiplies by x^32 and divides by the CRC polynomial.
+
+ - The polynomial is multiplied by x^32 and divided by G(x),
+ the generator polynomial, producing a remainder R(x) of
+ degree less than or equal to 31.
+
+ - The coefficients of R(x) are considered a 32-bit sequence.
+
+
+
+
+
+Stewart, et al. Informational [Page 83]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ - The bit sequence is complemented. The result is the CRC
+ polynomial.
+
+ - The CRC polynomial is mapped back into SCTP transport-level
+ bytes. The coefficient of x^31 gives the value of bit 7 of
+ SCTP byte 0, and the coefficient of x^24 gives the value of
+ bit 0 of byte 0. The coefficient of x^7 gives bit 7 of
+ byte 3, and the coefficient of x^0 gives bit 0 of byte 3.
+ The resulting four-byte transport-level sequence is the
+ 32-bit SCTP checksum value.
+
+ IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+ literature on CRCs often follow an alternative formulation, in
+ which the register used to hold the remainder of the
+ long-division algorithm is initialized to zero rather than
+ all-1s, and instead the first 32 bits of the message are
+ complemented. The long-division algorithm used in our
+ formulation is specified such that the initial
+ multiplication by 2^32 and the long-division are combined into
+ one simultaneous operation. For such algorithms, and for
+ messages longer than 64 bits, the two specifications are
+ precisely equivalent. That equivalence is the intent of
+ this document.
+
+ Implementors of SCTP are warned that both specifications are to be
+ found in the literature, sometimes with no restriction on the
+ long-division algorithm. The choice of formulation in this
+ document is to permit non-SCTP usage, where the same CRC
+ algorithm may be used to protect messages shorter than 64 bits.
+
+ There may be a computational advantage in validating the
+ Association against the Verification Tag, prior to performing a
+ checksum, as invalid tags will result in the same action as a bad
+ checksum in most cases. The exceptions for this technique would
+ be INIT and some SHUTDOWN-COMPLETE exchanges, as well as a stale
+ COOKIE-ECHO. These special case exchanges must represent small
+ packets and will minimize the effect of the checksum calculation.
+
+
+ ---------
+ Old text: (Section 18)
+ ---------
+
+ 18. Bibliography
+
+ [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+ Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+
+
+
+Stewart, et al. Informational [Page 84]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP, Computer Communications Review,
+ V. 26 N. 3, July 1996, pp. 5-21.
+
+ [RFC1750] Eastlake, D. (ed.), "Randomness Recommendations for
+ Security", RFC 1750, December 1994.
+
+ [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, March 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management
+ Protocol", RFC 2522, March 1999.
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+ "TCP Congestion Control with a Misbehaving Receiver", ACM
+ Computer Communication Review, 29(5), October 1999.
+
+ ---------
+ New text: (Section 18, including changes from 2.11)
+ ---------
+
+ 18. Bibliography
+
+ [ALLMAN99] Allman, M. and Paxson, V., "On Estimating End-to-End
+ Network Path Properties", Proc. SIGCOMM'99, 1999.
+
+ [FALL96] Fall, K. and Floyd, S., Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP, Computer Communications Review,
+ V. 26 N. 3, July 1996, pp. 5-21.
+
+ [ITU32] ITU-T Recommendation V.42, "Error-correcting
+ procedures for DCEs using asynchronous-to-synchronous
+ conversion", Section 8.1.1.6.2, October 1996.
+
+ [PETERSON 1972] W. W. Peterson and E.J Weldon, Error Correcting
+ Codes, 2nd Edition, MIT Press, Cambridge,
+ Massachusetts.
+
+ [RFC1750] Eastlake, D., Ed., "Randomness Recommendations for
+ Security", RFC 1750, December 1994.
+
+
+
+
+
+Stewart, et al. Informational [Page 85]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ [RFC1858] Ziemba, G., Reed, D. and Traina P., "Security
+ Considerations for IP Fragment Filtering", RFC 1858,
+ October 1995.
+
+ [RFC1950] Deutsch P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, March 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key Management
+ Protocol", RFC 2522, March 1999.
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and Anderson, T.,
+ "TCP Congestion Control with a Misbehaving Receiver", ACM
+ Computer Communication Review, 29(5), October 1999.
+
+ [WILLIAMS93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR
+ DETECTION ALGORITHMS" - Internet publication, August
+ 1993,
+ http://www.geocities.com/SiliconValley/Pines/
+ 8659/crc.htm.
+
+2.38.3. Solution Description
+
+ This change adds to the implementor's guide the complete set of
+ changes that, when combined with RFC 2960 [5], encompasses the
+ changes from RFC 3309 [6].
+
+2.39. Retransmission Policy
+
+2.39.1. Description of the Problem
+
+ The current retransmission policy (send all retransmissions an
+ alternate destination) in the specification has performance issues
+ under certain loss conditions with multihomed endpoints. Instead,
+ fast retransmissions should be sent to the same destination, and only
+ timeout retransmissions should be sent to an alternate destination
+ [4].
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 86]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.39.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.4)
+ ---------
+
+ Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+ retransmit a chunk to an active destination transport address that is
+ different from the last destination address to which the DATA chunk
+ was sent.
+
+ ---------
+ New text: (Section 6.4)
+ ---------
+
+ Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+ retransmit a chunk that timed out to an active destination transport
+ address that is different from the last destination address to which
+ the DATA chunk was sent.
+
+ ---------
+ Old text: (Section 6.4.1)
+ ---------
+
+ When retransmitting data, if the endpoint is multi-homed, it should
+ consider each source-destination address pair in its retransmission
+ selection policy. When retransmitting the endpoint should attempt to
+ pick the most divergent source-destination pair from the original
+ source-destination pair to which the packet was transmitted.
+
+ ---------
+ New text: (Section 6.4.1)
+ ---------
+
+ When retransmitting data that timed out, if the endpoint is
+ multi-homed, it should consider each source-destination address
+ pair in its retransmission selection policy. When retransmitting
+ timed out data, the endpoint should attempt to pick the most
+ divergent source-destination pair from the original
+ source-destination pair to which the packet was transmitted.
+
+2.39.3. Solution Description
+
+ The above wording changes clarify that only timeout retransmissions
+ should be sent to an alternate active destination.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 87]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.40. Port Number 0
+
+2.40.1. Description of the Problem
+
+ The port number 0 has a special semantic in various APIs. For
+ example, in the socket API, if the user specifies 0, the SCTP
+ implementation chooses an appropriate port number for the user.
+ Therefore, the port number 0 should not be used on the wire.
+
+2.40.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.1)
+ ---------
+
+ Source Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP sender's port number. It can be used by the
+ receiver in combination with the source IP address, the SCTP
+ destination port, and possibly the destination IP address to
+ identify the association to which this packet belongs.
+
+ Destination Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP port number to which this packet is destined.
+ The receiving host will use this port number to de-multiplex
+ the SCTP packet to the correct receiving endpoint/application.
+
+ ---------
+ New text: (Section 3.1)
+ ---------
+
+ Source Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP sender's port number. It can be used by the
+ receiver in combination with the source IP address, the SCTP
+ destination port and possibly the destination IP address to
+ identify the association to which this packet belongs.
+ The port number 0 MUST NOT be used.
+
+ Destination Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP port number to which this packet is destined.
+ The receiving host will use this port number to de-multiplex
+ the SCTP packet to the correct receiving endpoint/application.
+ The port number 0 MUST NOT be used.
+
+
+
+
+
+Stewart, et al. Informational [Page 88]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.40.3. Solution Description
+
+ It is clearly stated that the port number 0 is an invalid value on
+ the wire.
+
+2.41. T Bit
+
+2.41.1. Description of the Problem
+
+ The description of the T bit as the bit describing whether a TCB has
+ been destroyed is misleading. In addition, the procedure described
+ in Section 2.13 is not as precise as needed.
+
+2.41.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.7)
+ ---------
+
+ T bit: 1 bit
+ The T bit is set to 0 if the sender had a TCB that it
+ destroyed. If the sender did not have a TCB it should set
+ this bit to 1.
+
+ ---------
+ New text: (Section 3.3.7)
+ ---------
+
+ T bit: 1 bit
+ The T bit is set to 0 if the sender filled in the
+ Verification Tag expected by the peer. If the Verification
+ Tag is reflected, the T bit MUST be set to 1. Reflecting means
+ that the sent Verification Tag is the same as the received
+ one.
+
+
+ ---------
+ Old text: (Section 3.3.13)
+ ---------
+
+ T bit: 1 bit
+ The T bit is set to 0 if the sender had a TCB that it
+ destroyed. If the sender did not have a TCB it should set
+ this bit to 1.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 89]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 3.3.13)
+ ---------
+
+ T bit: 1 bit
+ The T bit is set to 0 if the sender filled in the
+ Verification Tag expected by the peer. If the Verification
+ Tag is reflected, the T bit MUST be set to 1. Reflecting means
+ that the sent Verification Tag is the same as the received
+ one.
+
+
+ ---------
+ Old text: (Section 8.4)
+ ---------
+
+ 3) If the packet contains an INIT chunk with a Verification Tag
+ set to '0', process it as described in Section 5.1.
+ Otherwise,
+
+ ---------
+ New text: (Section 8.4)
+ ---------
+ 3) If the packet contains an INIT chunk with a Verification Tag
+ set to '0', process it as described in Section 5.1. If, for
+ whatever reason, the INIT cannot be processed normally and
+ an ABORT has to be sent in response, the Verification Tag of
+ the packet containing the ABORT chunk MUST be the Initiate
+ tag of the received INIT chunk, and the T-Bit of the ABORT
+ chunk has to be set to 0, indicating that the Verification
+ Tag is NOT reflected.
+
+
+ ---------
+ Old text: (Section 8.4)
+ ---------
+ 5) If the packet contains a SHUTDOWN ACK chunk, the receiver
+ should respond to the sender of the OOTB packet with a
+ SHUTDOWN COMPLETE. When sending the SHUTDOWN COMPLETE, the
+ receiver of the OOTB packet must fill in the Verification
+ Tag field of the outbound packet with the Verification Tag
+ received in the SHUTDOWN ACK and set the T-bit in the Chunk
+ Flags to indicate that no TCB was found. Otherwise,
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 90]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Section 8.4)
+ ---------
+
+ 5) If the packet contains a SHUTDOWN ACK chunk, the receiver
+ should respond to the sender of the OOTB packet with a
+ SHUTDOWN COMPLETE. When sending the SHUTDOWN COMPLETE, the
+ receiver of the OOTB packet must fill in the Verification
+ Tag field of the outbound packet with the Verification Tag
+ received in the SHUTDOWN ACK and set the T-bit in the
+ Chunk Flags to indicate that the Verification Tag is
+ reflected. Otherwise,
+
+
+ ---------
+ Old text: (Section 8.4)
+ ---------
+
+ 8) The receiver should respond to the sender of the OOTB packet
+ with an ABORT. When sending the ABORT, the receiver of the
+ OOTB packet MUST fill in the Verification Tag field of the
+ outbound packet with the value found in the Verification
+ Tag field of the OOTB packet and set the T-bit in the Chunk
+ Flags to indicate that no TCB was found. After sending this
+ ABORT, the receiver of the OOTB packet shall discard the
+ OOTB packet and take no further action.
+
+ ---------
+ New text: (Section 8.4)
+ ---------
+
+ 8) The receiver should respond to the sender of the OOTB packet
+ with an ABORT. When sending the ABORT, the receiver of the
+ OOTB packet MUST fill in the Verification Tag field of the
+ outbound packet with the value found in the Verification Tag
+ field of the OOTB packet and set the T-bit in the Chunk Flags
+ to indicate that the Verification Tag is reflected. After
+ sending this ABORT, the receiver of the OOTB packet shall
+ discard the OOTB packet and take no further action.
+
+
+ ---------
+ Old text: (Section 8.5.1)
+ ---------
+
+ B) Rules for packet carrying ABORT:
+
+
+
+
+
+Stewart, et al. Informational [Page 91]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ - The endpoint shall always fill in the Verification Tag
+ field of the outbound packet with the destination
+ endpoint's tag value if it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the
+ endpoint MUST follow the procedure described in
+ Section 8.4.
+
+ - The receiver MUST accept the packet if the Verification
+ Tag matches either its own tag, OR the tag of its peer.
+ Otherwise, the receiver MUST silently discard the packet
+ and take no further action.
+
+ ---------
+ New text: (Section 8.5.1)
+ ---------
+
+ B) Rules for packet carrying ABORT:
+
+ - The endpoint MUST always fill in the Verification Tag
+ field of the outbound packet with the destination
+ endpoint's tag value, if it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the
+ endpoint MUST follow the procedure described in
+ Section 8.4.
+
+ - The receiver of an ABORT MUST accept the packet
+ if the Verification Tag field of the packet matches its
+ own tag and the T bit is not set
+ OR
+ if it is set to its peer's tag and the T bit is set in
+ the Chunk Flags.
+ Otherwise, the receiver MUST silently discard the packet
+ and take no further action.
+
+
+ ---------
+ Old text: (Section 8.5.1)
+ ---------
+
+ C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+ - When sending a SHUTDOWN COMPLETE, if the receiver of the
+ SHUTDOWN ACK has a TCB then the destination endpoint's
+ tag MUST be used. Only where no TCB exists should the
+ sender use the Verification Tag from the SHUTDOWN ACK.
+
+
+
+
+Stewart, et al. Informational [Page 92]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ - The receiver of a SHUTDOWN COMPLETE shall accept the
+ packet if the Verification Tag field of the packet matches
+ its own tag OR it is set to its peer's tag and the T bit
+ is set in the Chunk Flags. Otherwise, the receiver MUST
+ silently discard the packet and take no further action.
+ An endpoint MUST ignore the SHUTDOWN COMPLETE if it is
+ not in the SHUTDOWN-ACK-SENT state.
+
+ ---------
+ New text: (Section 8.5.1)
+ ---------
+
+ C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+ - When sending a SHUTDOWN COMPLETE, if the receiver of the
+ SHUTDOWN ACK has a TCB, then the destination endpoint's tag
+ MUST be used, and the T-bit MUST NOT be set. Only where no
+ TCB exists should the sender use the Verification Tag from
+ the SHUTDOWN ACK, and MUST set the T-bit.
+
+ - The receiver of a SHUTDOWN COMPLETE shall accept the packet
+ if the Verification Tag field of the packet matches its own
+ tag and the T bit is not set
+ OR
+ if it is set to its peer's tag and the T bit is set in the
+ Chunk Flags.
+ Otherwise, the receiver MUST silently discard the packet
+ and take no further action. An endpoint MUST ignore the
+ SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT
+ state.
+
+2.41.3. Solution Description
+
+ The description of the T bit now clearly describes the semantic of
+ the bit. The procedures for receiving the T bit have been clarified.
+
+2.42. Unknown Parameter Handling
+
+2.42.1. Description of the Problem
+
+ The description given in Section 2.33 does not state clearly whether
+ an INIT-ACK or COOKIE-ECHO is sent.
+
+2.42.2. Text Changes to the Document
+
+ The changes given here already include changes suggested in Section
+ 2.2, 2.27, and 2.33 of this document.
+
+
+
+
+Stewart, et al. Informational [Page 93]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this SCTP packet and discard it do not process
+ any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not process
+ any further chunks within it, and report the unrecognized
+ parameter in an 'Unrecognized Parameter Type' (in either an
+ ERROR or in the INIT ACK).
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter Type' (in
+ either an ERROR or in the INIT ACK).
+
+ ---------
+ New text: (Section 3.2.1)
+ ---------
+
+ 00 - Stop processing this parameter; do not process
+ any further parameters within this chunk.
+
+ 01 - Stop processing this parameter, do not process
+ any further parameters within this chunk, and report the
+ unrecognized parameter in an 'Unrecognized Parameter', as
+ described in 3.2.2.
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter', as
+ described in 3.2.2.
+
+ Please note that in all four cases an INIT-ACK or COOKIE-ECHO
+ chunk is sent. In the 00 or 01 case the processing of the
+ parameters after the unknown parameter is canceled, but no
+ processing already done is rolled back.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 94]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ New text: (Note: no old text; clarification added in Section 3.2)
+ ---------
+
+ 3.2.2. Reporting of Unrecognized Parameters
+
+ If the receiver of an INIT chunk detects unrecognized parameters
+ and has to report them according to Section 3.2.1, it MUST put
+ the 'Unrecognized Parameter' parameter(s) in the INIT-ACK chunk
+ sent in response to the INIT-chunk. Note that if the receiver
+ of the INIT chunk is NOT going to establish an association (e.g.,
+ due to lack of resources), an 'Unrecognized Parameter' would NOT
+ be included with any ABORT being sent to the sender of the INIT.
+
+ If the receiver of an INIT-ACK chunk detects unrecognized
+ parameters and has to report them according to Section 3.2.1, it
+ SHOULD bundle the ERROR chunk containing the 'Unrecognized
+ Parameters' error cause with the COOKIE-ECHO chunk sent in
+ response to the INIT-ACK chunk. If the receiver of the INIT-ACK
+ cannot bundle the COOKIE-ECHO chunk with the ERROR chunk, the
+ ERROR chunk MAY be sent separately but not before the COOKIE-ACK
+ has been received.
+
+ Note: Any time a COOKIE-ECHO is sent in a packet, it MUST be the
+ first chunk.
+
+2.42.3. Solution Description
+
+ The new text clearly states that an INIT-ACK or COOKIE-ECHO has to be
+ sent.
+
+2.43. Cookie Echo Chunk
+
+2.43.1. Description of the Problem
+
+ The description given in Section 3.3.11 of RFC 2960 [5] is unclear as
+ to how the COOKIE-ECHO is composed.
+
+2.43.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.11)
+ ---------
+ Cookie: variable size
+
+ This field must contain the exact cookie received in the State
+ Cookie parameter from the previous INIT ACK.
+
+
+
+
+Stewart, et al. Informational [Page 95]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ An implementation SHOULD make the cookie as small as possible
+ to insure interoperability.
+
+ ---------
+ New text: (Section 3.3.11)
+ ---------
+ Cookie: variable size
+
+ This field must contain the exact cookie received in the State
+ Cookie parameter from the previous INIT ACK.
+
+ An implementation SHOULD make the cookie as small as possible
+ to ensure interoperability.
+
+ Note: A Cookie Echo does NOT contain a State Cookie
+ Parameter; instead, the data within the State Cookie's
+ Parameter Value becomes the data within the Cookie Echo's
+ Chunk Value. This allows an implementation to change only
+ the first two bytes of the State Cookie parameter to become
+ a Cookie Echo Chunk.
+
+2.43.3. Solution Description
+
+ The new text adds a note that helps clarify that a Cookie Echo chunk
+ is nothing more than the State Cookie parameter with only two bytes
+ modified.
+
+2.44. Partial Chunks
+
+2.44.1. Description of the Problem
+
+ Section 6.10 of RFC 2960 [5] uses the notion of 'partial chunks'
+ without defining it.
+
+2.44.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.10)
+ ---------
+ Partial chunks MUST NOT be placed in an SCTP packet.
+
+ ---------
+ New text: (Section 6.10)
+ ---------
+ Partial chunks MUST NOT be placed in an SCTP packet. A partial
+ chunk is a chunk that is not completely contained in the SCTP
+ packet; i.e., the SCTP packet is too short to contain all the bytes
+ of the chunk as indicated by the chunk length.
+
+
+
+Stewart, et al. Informational [Page 96]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.44.3. Solution Description
+
+ The new text adds a definition of 'partial chunks'.
+
+2.45. Non-unicast Addresses
+
+2.45.1. Description of the Problem
+
+ Section 8.4 of RFC 2960 [5] forces the OOTB handling to discard all
+ non-unicast addresses. This leaves future use of anycast addresses
+ in question. With the addition of the add-ip feature, SCTP should be
+ able to easily handle anycast INIT s that can be followed, after
+ association setup, with a delete of the anycast address from the
+ association.
+
+2.45.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 8.4)
+ ---------
+ 8.4 Handle "Out of the blue" Packets
+
+ An SCTP packet is called an "out of the blue" (OOTB) packet if
+ it is correctly formed, i.e., passed the receiver's Adler-32
+ check (see Section 6.8), but the receiver is not able to
+ identify the association to which this packet belongs.
+
+ The receiver of an OOTB packet MUST do the following:
+
+ 1) If the OOTB packet is to or from a non-unicast address,
+ silently discard the packet. Otherwise,
+
+
+ ---------
+ New text: (Section 8.4)
+ ---------
+
+ 8.4. Handle "Out of the Blue" Packets
+
+ An SCTP packet is called an "out of the blue" (OOTB) packet if
+ it is correctly formed (i.e., passed the receiver's CRC32c
+ check; see Section 6.8), but the receiver is not able to identify
+ the association to which this packet belongs.
+
+ The receiver of an OOTB packet MUST do the following:
+
+ 1) If the OOTB packet is to or from a non-unicast address, a
+ receiver SHOULD silently discard the packet. Otherwise,
+
+
+
+Stewart, et al. Informational [Page 97]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.45.3. Solution Description
+
+ The loosening of the wording to a SHOULD will now allow future use of
+ anycast addresses. Note that no changes are made to Section
+ 11.2.4.1, since responding to broadcast addresses could lead to
+ flooding attacks and implementors should pay careful attention to
+ these words.
+
+2.46. Processing of ABORT Chunks
+
+2.46.1. Description of the Problem
+
+ Section 3.3.7 of RFC 2960 [5] requires an SCTP endpoint to silently
+ discard ABORT chunks received for associations that do not exist. It
+ is not clear what this means in the COOKIE-WAIT state, for example.
+ Therefore, it was not clear whether an ABORT sent in response to an
+ INIT should be processed or silently discarded.
+
+2.46.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.7)
+ ---------
+
+ If an endpoint receives an ABORT with a format error or for an
+ association that doesn't exist, it MUST silently discard it.
+
+ ---------
+ New text: (Section 3.3.7)
+ ---------
+
+ If an endpoint receives an ABORT with a format error or no
+ TCB is found, it MUST silently discard it.
+
+2.46.3. Solution Description
+
+ It is now clearly stated that an ABORT chunk should be processed
+ whenever a TCB is found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 98]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.47. Sending of ABORT Chunks
+
+2.47.1. Description of the Problem
+
+ Section 5.1 of RFC 2960 [5] requires that an ABORT chunk be sent in
+ response to an INIT chunk when there is no listening end point. To
+ make port scanning harder, someone might not want these ABORTs to be
+ received by the sender of the INIT chunks. Currently, the only way
+ to enforce this is by using a firewall that discards the packets
+ containing the INIT chunks or the packets containing the ABORT
+ chunks. It is desirable that the same can be done without a middle
+ box.
+
+2.47.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 5.1)
+ ---------
+
+ If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk
+ but decides not to establish the new association due to missing
+ mandatory parameters in the received INIT or INIT ACK, invalid
+ parameter values, or lack of local resources, it MUST respond with
+ an ABORT chunk.
+
+ ---------
+ New text: (Section 5.1)
+ ---------
+
+ If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk
+ but decides not to establish the new association due to missing
+ mandatory parameters in the received INIT or INIT ACK, invalid
+ parameter values, or lack of local resources, it SHOULD respond
+ with an ABORT chunk.
+
+2.47.3. Solution Description
+
+ The requirement of sending ABORT chunks is relaxed such that an
+ implementation can decide not to send ABORT chunks.
+
+2.48. Handling of Supported Address Types Parameter
+
+2.48.1. Description of the Problem
+
+ The sender of the INIT chunk can include a 'Supported Address Types'
+ parameter to indicate which address families are supported. It is
+ unclear how an INIT chunk should be processed where the source
+ address of the packet containing the INIT chunk or listed addresses
+
+
+
+Stewart, et al. Informational [Page 99]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ within the INIT chunk indicate that more address types are supported
+ than those listed in the 'Supported Address Types' parameter.
+
+2.48.2. Text Changes to the Document
+
+ The changes given here already include changes suggested in Section
+ 2.28 of this document.
+
+ ---------
+ Old text: (Section 5.1.2)
+ ---------
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type,
+ it can abort the initiation process and then attempt a
+ re-initiation by using a 'Supported Address Types' parameter in
+ the new INIT to indicate what types of address it prefers.
+
+ ---------
+ New text: (Section 5.1.2)
+ ---------
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type,
+ it can abort the initiation process and then attempt a re-
+ initiation by using a 'Supported Address Types' parameter in the
+ new INIT to indicate what types of address it prefers.
+
+ IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+ IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT-
+ ACK chunk from its peer, it MUST use all the addresses belonging
+ to the supported address family. The other addresses MAY be
+ ignored. The endpoint SHOULD NOT respond with any kind of error
+ indication.
+
+ IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported
+ Address Types' parameter either IPv4 or IPv6, but uses the other
+ family for sending the packet containing the INIT chunk, or if it
+ also lists addresses of the other family in the INIT chunk, then
+ the address family that is not listed in the 'Supported Address
+ Types' parameter SHOULD also be considered as supported by the
+ receiver of the INIT chunk. The receiver of the INIT chunk SHOULD
+ NOT respond with any kind of error indication.
+
+2.48.3. Solution Description
+
+ It is now clearly described how these Supported Address Types
+ parameters with incorrect data should be handled.
+
+
+
+Stewart, et al. Informational [Page 100]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.49. Handling of Unexpected Parameters
+
+2.49.1. Description of the Problem
+
+ RFC 2960 [5] clearly describes how unknown parameters in the INIT and
+ INIT-ACK chunk should be processed. But it is not described how
+ unexpected parameters should be processed. A parameter is unexpected
+ if it is known and is an optional parameter in either the INIT or
+ INIT-ACK chunk but is received in the chunk for which it is not an
+ optional parameter. For example, the 'Supported Address Types'
+ parameter would be an unexpected parameter if contained in an INIT-
+ ACK chunk.
+
+2.49.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.2)
+ ---------
+
+ Note 4: This parameter, when present, specifies all the address
+ types the sending endpoint can support. The absence of this
+ parameter indicates that the sending endpoint can support any
+ address type.
+
+ ---------
+ New text: (Section 3.3.2)
+ ---------
+
+ Note 4: This parameter, when present, specifies all the address
+ types the sending endpoint can support. The absence of this
+ parameter indicates that the sending endpoint can support any
+ address type.
+
+ IMPLEMENTATION NOTE: If an INIT chunk is received with known
+ parameters that are not optional parameters of the INIT chunk
+ then the receiver SHOULD process the INIT chunk and send back
+ an INIT-ACK. The receiver of the INIT chunk MAY bundle an ERROR
+ chunk with the COOKIE-ACK chunk later. However, restrictive
+ implementations MAY send back an ABORT chunk in response to
+ the INIT chunk.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 101]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ ---------
+ Old text: (Section 3.3.3)
+ ---------
+
+ IMPLEMENTATION NOTE: An implementation MUST be prepared to receive
+ a INIT ACK that is quite large (more than 1500 bytes) due to the
+ variable size of the state cookie AND the variable address list.
+ For example if a responder to the INIT has 1000 IPv4 addresses
+ it wishes to send, it would need at least 8,000 bytes to encode
+ this in the INIT ACK.
+
+ ---------
+ New text: (Section 3.3.3)
+ ---------
+
+ IMPLEMENTATION NOTE: An implementation MUST be prepared to receive
+ a INIT ACK that is quite large (more than 1500 bytes) due to the
+ variable size of the state cookie AND the variable address list.
+ For example, if a responder to the INIT has 1000 IPv4 addresses
+ it wishes to send, it would need at least 8,000 bytes to encode
+ this in the INIT ACK.
+
+ IMPLEMENTATION NOTE: If an INIT-ACK chunk is received with known
+ parameters that are not optional parameters of the INIT-ACK
+ chunk, then the receiver SHOULD process the INIT-ACK chunk and
+ send back a COOKIE-ECHO. The receiver of the INIT-ACK chunk
+ MAY bundle an ERROR chunk with the COOKIE-ECHO chunk. However,
+ restrictive implementations MAY send back an ABORT chunk in
+ response to the INIT-ACK chunk.
+
+2.49.3. Solution Description
+
+ It is now stated how unexpected parameters should be processed.
+
+2.50. Payload Protocol Identifier
+
+2.50.1. Description of the Problem
+
+ The current description of the payload protocol identifier does NOT
+ highlight the fact that the field is NOT necessarily in network byte
+ order.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 102]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.50.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 3.3.1)
+ ---------
+ Payload Protocol Identifier: 32 bits (unsigned integer)
+
+ This value represents an application (or upper layer) specified
+ protocol identifier. This value is passed to SCTP by its upper
+ layer and sent to its peer. This identifier is not used by
+ SCTP but can be used by certain network entities as well as
+ the peer application to identify the type of information being
+ carried in this DATA chunk. This field must be sent even in
+ fragmented DATA chunks (to make sure it is available for agents
+ in the middle of the network).
+
+ The value 0 indicates no application identifier is specified by
+ the upper layer for this payload data.
+
+ ---------
+ New text: (Section 3.3.1)
+ ---------
+ Payload Protocol Identifier: 32 bits (unsigned integer)
+
+ This value represents an application (or upper layer) specified
+ protocol identifier. This value is passed to SCTP by its upper
+ layer and sent to its peer. This identifier is not used by
+ SCTP but can be used by certain network entities, as well as by
+ the peer application, to identify the type of information being
+ carried in this DATA chunk. This field must be sent even in
+ fragmented DATA chunks (to make sure it is available for agents
+ in the middle of the network). Note that this field is NOT
+ touched by an SCTP implementation, therefore its byte order is
+ NOT necessarily Big Endian. The upper layer is responsible
+ for any byte order conversions to this field.
+
+ The value 0 indicates that no application identifier is
+ specified by the upper layer for this payload data.
+
+2.50.3. Solution Description
+
+ It is now explicitly stated that the upper layer is responsible for
+ the byte order of this field.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 103]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.51. Karn's Algorithm
+
+2.51.1. Description of the Problem
+
+ The current wording of the use of Karn's algorithm is not descriptive
+ enough to ensure that an implementation in a multi-homed association
+ does not incorrectly mismeasure the RTT.
+
+2.51.2. Text Changes to the Document
+
+ ---------
+ Old text: (Section 6.3.1)
+ ---------
+
+ C5) Karn's algorithm: RTT measurements MUST NOT be made using
+ packets that were retransmitted (and thus for which it is
+ ambiguous whether the reply was for the first instance of the
+ packet or a later instance)
+ ---------
+ New text: (Section 6.3.1)
+ ---------
+
+ C5) Karn's algorithm: RTT measurements MUST NOT be made using
+ chunks that were retransmitted (and thus for which it is
+ ambiguous whether the reply was for the first instance of
+ the chunk or for a later instance)
+
+ IMPLEMENTATION NOTE: RTT measurements should only be
+ made using a chunk with TSN r if no chunk
+ with TSN less than or equal to r is retransmitted
+ since r is first sent.
+
+2.51.3. Solution Description
+
+ The above clarification adds an implementation note that will provide
+ additional guidance in the application of Karn's algorithm.
+
+2.52. Fast Retransmit Algorithm
+
+2.52.1. Description of the Problem
+
+ The original SCTP specification is overly conservative in requiring 4
+ missing reports before fast retransmitting a segment. TCP uses 3
+ missing reports or 4 acknowledgements indicating that the same
+ segment was received.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 104]
+
+RFC 4460 SCTP Errata April 2006
+
+
+2.52.2. Text Changes to the Document
+
+ ---------
+ Old text:
+ ---------
+
+ 7.2.4 Fast Retransmit on Gap Reports
+
+ In the absence of data loss, an endpoint performs delayed
+ acknowledgement. However, whenever an endpoint notices a hole in
+ the arriving TSN sequence, it SHOULD start sending a SACK back
+ every time a packet arrives carrying data until the
+ hole is filled.
+
+ Whenever an endpoint receives a SACK that indicates some TSN(s)
+ missing, it SHOULD wait for 3 further miss indications (via
+ subsequent SACK's) on the same TSN(s) before taking action with
+ regard to Fast Retransmit.
+
+
+ ---------
+ New text:
+ ---------
+
+ 7.2.4. Fast Retransmit on Gap Reports
+
+ In the absence of data loss, an endpoint performs delayed
+ acknowledgement. However, whenever an endpoint notices a hole in
+ the arriving TSN sequence, it SHOULD start sending a SACK back
+ every time a packet arrives carrying data until the
+ hole is filled.
+
+ Whenever an endpoint receives a SACK that indicates that some
+ TSNs are missing, it SHOULD wait for 2 further miss indications
+ (via subsequent SACKs for a total of 3 missing reports) on the
+ same TSNs before taking action with regard to Fast Retransmit.
+
+2.52.3. Solution Description
+
+ The above changes will make SCTP and TCP behave similarly in terms of
+ how fast they engage the Fast Retransmission algorithm upon receiving
+ missing reports.
+
+3. Security Considerations
+
+ This document should add no additional security risks to SCTP and in
+ fact SHOULD correct some original security flaws within the original
+ document once it is incorporated into a RFC 2960 [5] BIS document.
+
+
+
+Stewart, et al. Informational [Page 105]
+
+RFC 4460 SCTP Errata April 2006
+
+
+4. Acknowledgements
+
+ The authors would like to thank the following people who have
+ provided comments and input for this document:
+
+ Barry Zuckerman, La Monte Yarroll, Qiaobing Xie, Wang Xiaopeng,
+ Jonathan Wood, Jeff Waskow, Mike Turner, John Townsend, Sabina
+ Torrente, Cliff Thomas, Yuji Suzuki, Manoj Solanki, Sverre Slotte,
+ Keyur Shah, Jan Rovins, Ben Robinson, Renee Revis, Ian Periam, RC
+ Monee, Sanjay Rao, Sujith Radhakrishnan, Heinz Prantner, Biren Patel,
+ Nathalie Mouellic, Mitch Miers, Bernward Meyknecht, Stan McClellan,
+ Oliver Mayor, Tomas Orti Martin, Sandeep Mahajan, David Lehmann,
+ Jonathan Lee, Philippe Langlois, Karl Knutson, Joe Keller, Gareth
+ Keily, Andreas Jungmaier, Janardhan Iyengar, Mutsuya Irie, John
+ Hebert, Kausar Hassan, Fred Hasle, Dan Harrison, Jon Grim, Laurent
+ Glaude, Steven Furniss, Atsushi Fukumoto, Ken Fujita, Steve Dimig,
+ Thomas Curran, Serkan Cil, Melissa Campbell, Peter Butler, Rob
+ Brennan, Harsh Bhondwe, Brian Bidulock, Caitlin Bestler, Jon Berger,
+ Robby Benedyk, Stephen Baucke, Sandeep Balani, and Ronnie Sellar.
+
+ A special thanks to Mark Allman, who should actually be a co-author
+ for his work on the max-burst, but managed to wiggle out due to a
+ technicality. Also, we would like to acknowledge Lyndon Ong and Phil
+ Conrad for their valuable input and many contributions.
+
+5. IANA Considerations
+
+ This document recommends changes for the RFC 2960 [5] BIS document.
+ As such, even though it lists new error cause code, this document in
+ itself does NOT define those new codes. Instead, the BIS document
+ will make the needed changes to RFC 2960 [5] and thus its IANA
+ section will require changes to be made.
+
+6. Normative References
+
+ [1] Braden, R., "Requirements for Internet Hosts - Communication
+ Layers", STD 3, RFC 1122, October 1989.
+
+ [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [3] Caro, A., Shah, K., Iyengar, J., Amer, P., and R. Stewart, "SCTP
+ and TCP Variants: Congestion Control Under Multiple Losses",
+ Technical Report TR2003-04, Computer and Information Sciences
+ Department, University of Delaware, February 2003,
+ <http://www.armandocaro.net/papers>.
+
+
+
+
+
+Stewart, et al. Informational [Page 106]
+
+RFC 4460 SCTP Errata April 2006
+
+
+ [4] Caro, A., Amer, P., and R. Stewart, "Retransmission Schemes for
+ End-to-end Failover with Transport Layer Multihoming", GLOBECOM,
+ November 2004., <http://www.armandocaro.net/papers>.
+
+ [5] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V.
+ Paxson, "Stream Control Transmission Protocol", RFC 2960,
+ October 2000.
+
+ [6] Stone, J., Stewart, R., and D. Otis, "Stream Control
+ Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+ September 2002.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 107]
+
+RFC 4460 SCTP Errata April 2006
+
+
+Authors' Addresses
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 4875 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ USA
+
+ EMail: rrs@cisco.com
+
+
+ Ivan Arias-Rodriguez
+ Nokia Research Center
+ PO Box 407
+ FIN-00045 Nokia Group
+ Finland
+
+ EMail: ivan.arias-rodriguez@nokia.com
+
+
+ Kacheong Poon
+ Sun Microsystems, Inc.
+ 3571 N. First St.
+ San Jose, CA 95134
+ USA
+
+ EMail: kacheong.poon@sun.com
+
+
+ Armando L. Caro Jr.
+ BBN Technologies
+ 10 Moulton St.
+ Cambridge, MA 02138
+
+ EMail: acaro@bbn.com
+ URI: http://www.armandocaro.net
+
+
+ Michael Tuexen
+ Muenster Univ. of Applied Sciences
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+
+
+
+Stewart, et al. Informational [Page 108]
+
+RFC 4460 SCTP Errata April 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 109]
+
diff --git a/doc/rfc4820.txt b/doc/rfc4820.txt
new file mode 100644
index 0000000..4b9b241
--- /dev/null
+++ b/doc/rfc4820.txt
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+Network Working Group M. Tuexen
+Request for Comments: 4820 Muenster Univ. of Applied Sciences
+Category: Standards Track R. Stewart
+ P. Lei
+ Cisco Systems, Inc.
+ March 2007
+
+
+ Padding Chunk and Parameter
+ for the Stream Control Transmission Protocol (SCTP)
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The IETF Trust (2007).
+
+Abstract
+
+ This document defines a padding chunk and a padding parameter and
+ describes the required receiver side procedures. The padding chunk
+ is used to pad a Stream Control Transmission Protocol (SCTP) packet
+ to an arbitrary size. The padding parameter is used to pad an SCTP
+ INIT chunk to an arbitrary size.
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 3. Padding Chunk (PAD) . . . . . . . . . . . . . . . . . . . . . . 2
+ 4. Padding Parameter (PAD) . . . . . . . . . . . . . . . . . . . . 3
+ 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 4
+ 5.1. A New Chunk Type . . . . . . . . . . . . . . . . . . . . . 4
+ 5.2. A New Parameter Type . . . . . . . . . . . . . . . . . . . 4
+ 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 4
+ 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 5
+ 8.1. Normative References . . . . . . . . . . . . . . . . . . . 5
+ 8.2. Informative References . . . . . . . . . . . . . . . . . . 5
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 1]
+
+RFC 4820 Padding Chunk and Parameter for SCTP March 2007
+
+
+1. Introduction
+
+ This document defines a padding chunk and a padding parameter and
+ describes the required receiver side procedures. The padding chunk
+ is used to pad an SCTP packet to an arbitrary size. The padding
+ parameter is used to pad an SCTP INIT chunk to an arbitrary size.
+ The usage of the PAD chunk for path MTU discovery is described in
+ PMTU [4]. The inappropriate usage of the PAD parameter or PAD chunk
+ can result in wasted bandwidth.
+
+2. Conventions
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+ "OPTIONAL", when they appear in this document, are to be interpreted
+ as described in RFC 2119 [1].
+
+3. Padding Chunk (PAD)
+
+ This chunk is used to pad an SCTP packet. A PAD chunk can be used to
+ enlarge the packet by 4 to 65536 bytes in steps of 4 bytes. An SCTP
+ packet MAY contain multiple PAD chunks.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0x84 | Flags=0 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ \ Padding Data /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 1
+
+ Type: 1 byte (unsigned integer)
+ This value MUST be set to 0x84 for all PAD chunks.
+
+ Flags: 1 byte (unsigned integer)
+ This value SHOULD be set to zero on transmit and MUST be ignored
+ on receipt.
+
+ Length: 2 bytes (unsigned integer)
+ This value holds the length of the Padding Data plus 4.
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 2]
+
+RFC 4820 Padding Chunk and Parameter for SCTP March 2007
+
+
+ Padding Data: n bytes (unsigned integer)
+ This holds the Padding Data. The Padding Data MUST be ignored by
+ the receiver.
+
+ The receiver of the PAD chunk MUST discard this chunk and continue
+ processing the rest of the chunks in the packet. Please note that
+ this is also the required processing behavior for any unknown chunk
+ having the same highest-order two bits of the type as the PAD chunk.
+
+4. Padding Parameter (PAD)
+
+ This parameter is used to pad an INIT chunk. A PAD parameter can be
+ used to enlarge the INIT chunk by 4 bytes as the minimum to the
+ maximum size of the INIT chunk in steps of 4 bytes. An INIT chunk
+ MAY contain multiple PAD parameters.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 0x8005 | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ Padding Data \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 2
+
+ Parameter Type: 2 bytes (unsigned integer)
+ This value MUST be set to 0x8005.
+
+ Parameter Length: 2 bytes (unsigned integer)
+ This value holds the length of the Padding Data plus 4.
+
+ The PAD parameter MAY be included only in the INIT chunk. It MUST
+ NOT be included in any other chunk. The receiver of the PAD
+ parameter MUST silently discard this parameter and continue
+ processing the rest of the INIT chunk. This means that the size of
+ the generated COOKIE parameter in the INIT-ACK MUST NOT depend on the
+ existence of the PAD parameter in the INIT chunk. A receiver of a
+ PAD parameter MUST NOT include the PAD parameter within any State
+ Cookie parameter it generates.
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 3]
+
+RFC 4820 Padding Chunk and Parameter for SCTP March 2007
+
+
+5. IANA Considerations
+
+ This document is the reference for all registrations described in
+ this section. All registrations have been listed in the document
+ available at sctp-parameters [3]. The changes are described below.
+
+5.1. A New Chunk Type
+
+ A chunk type for the PAD chunk has been assigned by IANA. The value
+ has been assigned as described in Figure 1. The following has been
+ added to the "CHUNK TYPES" table of sctp-parameters [3]:
+
+ CHUNK TYPES
+
+ ID Value Chunk Type Reference
+ -------- ---------- ---------
+ 132(0x84) Padding Chunk (PAD) [RFC4820]
+
+5.2. A New Parameter Type
+
+ A parameter type has been assigned for the PAD parameter by IANA.
+ The value has been assigned as described in Figure 2. The following
+ has been added to the "CHUNK PARAMETER TYPES" table in sctp-
+ parameters [3]:
+
+ INIT Chunk Parameter Types
+
+ Chunk Parameter Type Value
+ -------------------- -----
+ Padding 32773(0x8005)
+
+6. Security Considerations
+
+ This document does not add any additional security considerations to
+ the ones given in RFC 2960 [2].
+
+7. Acknowledgments
+
+ The authors wish to thank Matthew J. Zekauskas and Lars Eggert for
+ their invaluable comments.
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 4]
+
+RFC 4820 Padding Chunk and Parameter for SCTP March 2007
+
+
+8. References
+
+8.1. Normative References
+
+ [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [2] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+8.2. Informative References
+
+ [3] "IANA registry",
+ <http://www.iana.org/assignments/sctp-parameters>.
+
+ [4] Mathis, M. and J. Heffner, "Packetization Layer Path MTU
+ Discovery", RFC 4821, March 2007.
+
+Authors' Addresses
+
+ Michael Tuexen
+ Muenster Univ. of Applied Sciences
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 4875 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ USA
+
+ EMail: rrs@cisco.com
+
+
+ Peter Lei
+ Cisco Systems, Inc.
+ 955 Happfield Dr.
+ Arlington Heights, IL 60004
+ US
+
+ Phone: +1 773 695-8201
+ EMail: peterlei@cisco.com
+
+
+
+Tuexen, et al. Standards Track [Page 5]
+
+RFC 4820 Padding Chunk and Parameter for SCTP March 2007
+
+
+Full Copyright Statement
+
+ Copyright (C) The IETF Trust (2007).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+ THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 6]
+
diff --git a/doc/rfc4895.txt b/doc/rfc4895.txt
new file mode 100644
index 0000000..e877f5a
--- /dev/null
+++ b/doc/rfc4895.txt
@@ -0,0 +1,1067 @@
+
+
+
+
+
+
+Network Working Group M. Tuexen
+Request for Comments: 4895 Muenster Univ. of Applied Sciences
+Category: Standards Track R. Stewart
+ P. Lei
+ Cisco Systems, Inc.
+ E. Rescorla
+ RTFM, Inc.
+ August 2007
+
+
+ Authenticated Chunks for
+ the Stream Control Transmission Protocol (SCTP)
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This document describes a new chunk type, several parameters, and
+ procedures for the Stream Control Transmission Protocol (SCTP). This
+ new chunk type can be used to authenticate SCTP chunks by using
+ shared keys between the sender and receiver. The new parameters are
+ used to establish the shared keys.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 1]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 3. New Parameter Types . . . . . . . . . . . . . . . . . . . . . 4
+ 3.1. Random Parameter (RANDOM) . . . . . . . . . . . . . . . . 4
+ 3.2. Chunk List Parameter (CHUNKS) . . . . . . . . . . . . . . 5
+ 3.3. Requested HMAC Algorithm Parameter (HMAC-ALGO) . . . . . . 6
+ 4. New Error Cause . . . . . . . . . . . . . . . . . . . . . . . 7
+ 4.1. Unsupported HMAC Identifier Error Cause . . . . . . . . . 7
+ 5. New Chunk Type . . . . . . . . . . . . . . . . . . . . . . . . 8
+ 5.1. Authentication Chunk (AUTH) . . . . . . . . . . . . . . . 8
+ 6. Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 10
+ 6.1. Establishment of an Association Shared Key . . . . . . . . 10
+ 6.2. Sending Authenticated Chunks . . . . . . . . . . . . . . . 11
+ 6.3. Receiving Authenticated Chunks . . . . . . . . . . . . . . 12
+ 7. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
+ 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15
+ 8.1. A New Chunk Type . . . . . . . . . . . . . . . . . . . . . 15
+ 8.2. Three New Parameter Types . . . . . . . . . . . . . . . . 15
+ 8.3. A New Error Cause . . . . . . . . . . . . . . . . . . . . 15
+ 8.4. A New Table for HMAC Identifiers . . . . . . . . . . . . . 16
+ 9. Security Considerations . . . . . . . . . . . . . . . . . . . 16
+ 10. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 17
+ 11. Normative References . . . . . . . . . . . . . . . . . . . . . 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 2]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+1. Introduction
+
+ SCTP uses 32-bit verification tags to protect itself against blind
+ attackers. These values are not changed during the lifetime of an
+ SCTP association.
+
+ Looking at new SCTP extensions, there is the need to have a method of
+ proving that an SCTP chunk(s) was really sent by the original peer
+ that started the association and not by a malicious attacker.
+
+ Using Transport Layer Security (TLS), as defined in RFC 3436 [6],
+ does not help because it only secures SCTP user data.
+
+ Therefore, an SCTP extension that provides a mechanism for deriving
+ shared keys for each association is presented. These association
+ shared keys are derived from endpoint pair shared keys, which are
+ configured and might be empty, and data that is exchanged during the
+ SCTP association setup.
+
+ The extension presented in this document allows an SCTP sender to
+ authenticate chunks using shared keys between the sender and
+ receiver. The receiver can then verify that the chunks are sent from
+ the sender and not from a malicious attacker (as long as the attacker
+ does not know an association shared key).
+
+ The extension described in this document places the result of a
+ Hashed Message Authentication Code (HMAC) computation before the data
+ covered by that computation. Placing it at the end of the packet
+ would have required placing a control chunk after DATA chunks in case
+ of authenticating DATA chunks. This would break the rule that
+ control chunks occur before DATA chunks in SCTP packets. It should
+ also be noted that putting the result of the HMAC computation after
+ the data being covered would not allow sending the packet during the
+ computation of the HMAC because the result of the HMAC computation is
+ needed to compute the CRC32C checksum of the SCTP packet, which is
+ placed in the common header of the SCTP packet.
+
+ The SCTP extension for Dynamic Address Reconfiguration (ADD-IP)
+ requires the usage of the extension described in this document. The
+ SCTP Partial Reliability Extension (PR-SCTP) can be used in
+ conjunction with the extension described in this document.
+
+2. Conventions
+
+ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+ "OPTIONAL", when they appear in this document, are to be interpreted
+ as described in RFC 2119 [3].
+
+
+
+Tuexen, et al. Standards Track [Page 3]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+3. New Parameter Types
+
+ This section defines the new parameter types that will be used to
+ negotiate the authentication during association setup. Table 1
+ illustrates the new parameter types.
+
+ +----------------+------------------------------------------------+
+ | Parameter Type | Parameter Name |
+ +----------------+------------------------------------------------+
+ | 0x8002 | Random Parameter (RANDOM) |
+ | 0x8003 | Chunk List Parameter (CHUNKS) |
+ | 0x8004 | Requested HMAC Algorithm Parameter (HMAC-ALGO) |
+ +----------------+------------------------------------------------+
+
+ Table 1
+
+ Note that the parameter format requires the receiver to ignore the
+ parameter and continue processing if the parameter is not understood.
+ This is accomplished (as described in RFC 2960 [5], Section 3.2.1.)
+ by the use of the upper bits of the parameter type.
+
+3.1. Random Parameter (RANDOM)
+
+ This parameter is used to carry a random number of an arbitrary
+ length.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 0x8002 | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ \ Random Number /
+ / +-------------------------------\
+ | | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 1
+
+ Parameter Type: 2 bytes (unsigned integer)
+ This value MUST be set to 0x8002.
+
+ Parameter Length: 2 bytes (unsigned integer)
+ This value is the length of the Random Number in bytes plus 4.
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 4]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ Random Number: n bytes (unsigned integer)
+ This value represents an arbitrary Random Number in network byte
+ order.
+
+ Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+ If the length of the Random Number is not a multiple of 4 bytes,
+ the sender MUST pad the parameter with all zero bytes to make the
+ parameter 32-bit aligned. The Padding MUST NOT be longer than 3
+ bytes and it MUST be ignored by the receiver.
+
+ The RANDOM parameter MUST be included once in the INIT or INIT-ACK
+ chunk, if the sender wants to send or receive authenticated chunks,
+ to provide a 32-byte Random Number. For 32-byte Random Numbers, the
+ Padding is empty.
+
+3.2. Chunk List Parameter (CHUNKS)
+
+ This parameter is used to specify which chunk types are required to
+ be authenticated before being sent by the peer.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 0x8003 | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type 1 | Chunk Type 2 | Chunk Type 3 | Chunk Type 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type n | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 2
+
+ Parameter Type: 2 bytes (unsigned integer)
+ This value MUST be set to 0x8003.
+
+ Parameter Length: 2 bytes (unsigned integer)
+ This value is the number of listed Chunk Types plus 4.
+
+ Chunk Type n: 1 byte (unsigned integer)
+ Each Chunk Type listed is required to be authenticated when sent
+ by the peer.
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 5]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+ If the number of Chunk Types is not a multiple of 4, the sender
+ MUST pad the parameter with all zero bytes to make the parameter
+ 32-bit aligned. The Padding MUST NOT be longer than 3 bytes and
+ it MUST be ignored by the receiver.
+
+ The CHUNKS parameter MUST be included once in the INIT or INIT-ACK
+ chunk if the sender wants to receive authenticated chunks. Its
+ maximum length is 260 bytes.
+
+ The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE, and AUTH
+ chunks MUST NOT be listed in the CHUNKS parameter. However, if a
+ CHUNKS parameter is received then the types for INIT, INIT-ACK,
+ SHUTDOWN-COMPLETE, and AUTH chunks MUST be ignored.
+
+3.3. Requested HMAC Algorithm Parameter (HMAC-ALGO)
+
+ This parameter is used to list the HMAC Identifiers the peer MUST
+ use.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 0x8004 | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | HMAC Identifier 1 | HMAC Identifier 2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | HMAC Identifier n | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 3
+
+ Parameter Type: 2 bytes (unsigned integer)
+ This value MUST be set to 0x8004.
+
+ Parameter Length: 2 bytes (unsigned integer)
+ This value is the number of HMAC Identifiers multiplied by 2, plus
+ 4.
+
+ HMAC Identifier n: 2 bytes (unsigned integer)
+ The values expressed are a list of HMAC Identifiers that may be
+ used by the peer. The values are listed by preference, with
+ respect to the sender, where the first HMAC Identifier listed is
+ the one most preferable to the sender.
+
+
+
+Tuexen, et al. Standards Track [Page 6]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ Padding: 0 or 2 bytes (unsigned integer)
+ If the number of HMAC Identifiers is not even, the sender MUST pad
+ the parameter with all zero bytes to make the parameter 32-bit
+ aligned. The Padding MUST be 0 or 2 bytes long and it MUST be
+ ignored by the receiver.
+
+ The HMAC-ALGO parameter MUST be included once in the INIT or INIT-ACK
+ chunk if the sender wants to send or receive authenticated chunks.
+
+ Table 2 shows the currently defined values for HMAC Identifiers.
+
+ +-----------------+--------------------------+
+ | HMAC Identifier | Message Digest Algorithm |
+ +-----------------+--------------------------+
+ | 0 | Reserved |
+ | 1 | SHA-1 defined in [8] |
+ | 2 | Reserved |
+ | 3 | SHA-256 defined in [8] |
+ +-----------------+--------------------------+
+
+ Table 2
+
+ Every endpoint supporting SCTP chunk authentication MUST support the
+ HMAC based on the SHA-1 algorithm.
+
+4. New Error Cause
+
+ This section defines a new error cause that will be sent if an AUTH
+ chunk is received with an unsupported HMAC Identifier. Table 3
+ illustrates the new error cause.
+
+ +------------+-----------------------------+
+ | Cause Code | Error Cause Name |
+ +------------+-----------------------------+
+ | 0x0105 | Unsupported HMAC Identifier |
+ +------------+-----------------------------+
+
+ Table 3
+
+4.1. Unsupported HMAC Identifier Error Cause
+
+ This error cause is used to indicate that an AUTH chunk has been
+ received with an unsupported HMAC Identifier.
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 7]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code = 0x0105 | Cause Length = 6 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | HMAC Identifier | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 4
+
+ Cause Code: 2 bytes (unsigned integer)
+ This value MUST be set to 0x0105.
+
+ Cause Length: 2 bytes (unsigned integer)
+ This value MUST be set to 6.
+
+ HMAC Identifier: 2 bytes (unsigned integer)
+ This value is the HMAC Identifier which is not supported.
+
+ Padding: 2 bytes (unsigned integer)
+ The sender MUST pad the error cause with all zero bytes to make
+ the cause 32-bit aligned. The Padding MUST be 2 bytes long and it
+ MUST be ignored by the receiver.
+
+5. New Chunk Type
+
+ This section defines the new chunk type that will be used to
+ authenticate chunks. Table 4 illustrates the new chunk type.
+
+ +------------+-----------------------------+
+ | Chunk Type | Chunk Name |
+ +------------+-----------------------------+
+ | 0x0F | Authentication Chunk (AUTH) |
+ +------------+-----------------------------+
+
+ Table 4
+
+ It should be noted that the AUTH-chunk format requires the receiver
+ to ignore the chunk if it is not understood and silently discard all
+ chunks that follow. This is accomplished (as described in RFC 2960
+ [5], Section 3.2.) by the use of the upper bits of the chunk type.
+
+5.1. Authentication Chunk (AUTH)
+
+ This chunk is used to hold the result of the HMAC calculation.
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 8]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0x0F | Flags=0 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Shared Key Identifier | HMAC Identifier |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ \ HMAC /
+ / \
+ / +-------------------------------\
+ | | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 5
+
+ Type: 1 byte (unsigned integer)
+ This value MUST be set to 0x0F for all AUTH-chunks.
+
+ Flags: 1 byte (unsigned integer)
+ SHOULD be set to zero on transmit and MUST be ignored on receipt.
+
+ Length: 2 bytes (unsigned integer)
+ This value holds the length of the HMAC in bytes plus 8.
+
+ Shared Key Identifier: 2 bytes (unsigned integer)
+ This value describes which endpoint pair shared key is used.
+
+ HMAC Identifier: 2 bytes (unsigned integer)
+ This value describes which message digest is being used. Table 2
+ shows the currently defined values.
+
+ HMAC: n bytes (unsigned integer)
+ This holds the result of the HMAC calculation.
+
+ Padding: 0, 1, 2, or 3 bytes (unsigned integer)
+ If the length of the HMAC is not a multiple of 4 bytes, the sender
+ MUST pad the chunk with all zero bytes to make the chunk 32-bit
+ aligned. The Padding MUST NOT be longer than 3 bytes and it MUST
+ be ignored by the receiver.
+
+ The control chunk AUTH MUST NOT appear more than once in an SCTP
+ packet. All control and data chunks that are placed after the AUTH
+ chunk in the packet are sent in an authenticated way. Those chunks
+ placed in a packet before the AUTH chunk are not authenticated.
+ Please note that DATA chunks can not appear before control chunks in
+ an SCTP packet.
+
+
+
+
+Tuexen, et al. Standards Track [Page 9]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+6. Procedures
+
+6.1. Establishment of an Association Shared Key
+
+ An SCTP endpoint willing to receive or send authenticated chunks MUST
+ send one RANDOM parameter in its INIT or INIT-ACK chunk. The RANDOM
+ parameter MUST contain a 32-byte Random Number. The Random Number
+ should be generated in accordance with RFC 4086 [7]. If the Random
+ Number is not 32 bytes, the association MUST be aborted. The ABORT
+ chunk SHOULD contain the error cause 'Protocol Violation'. In case
+ of INIT collision, the rules governing the handling of this Random
+ Number follow the same pattern as those for the Verification Tag, as
+ explained in Section 5.2.4 of RFC 2960 [5]. Therefore, each endpoint
+ knows its own Random Number and the peer's Random Number after the
+ association has been established.
+
+ An SCTP endpoint has a list of chunks it only accepts if they are
+ received in an authenticated way. This list is included in the INIT
+ and INIT-ACK, and MAY be omitted if it is empty. Since this list
+ does not change during the lifetime of the SCTP endpoint there is no
+ problem in case of INIT collision.
+
+ Each SCTP endpoint MUST include in the INIT and INIT-ACK a HMAC-ALGO
+ parameter containing a list of HMAC Identifiers it requests the peer
+ to use. The receiver of an HMAC-ALGO parameter SHOULD use the first
+ listed algorithm it supports. The HMAC algorithm based on SHA-1 MUST
+ be supported and included in the HMAC-ALGO parameter. An SCTP
+ endpoint MUST NOT change the parameters listed in the HMAC-ALGO
+ parameter during the lifetime of the endpoint.
+
+ Both endpoints of an association MAY have endpoint pair shared keys
+ that are byte vectors and pre-configured or established by another
+ mechanism. They are identified by the Shared Key Identifier. For
+ each endpoint pair shared key, an association shared key is computed.
+ If there is no endpoint pair shared key, only one association shared
+ key is computed by using an empty byte vector as the endpoint pair
+ shared key.
+
+ The RANDOM parameter, the CHUNKS parameter, and the HMAC-ALGO
+ parameter sent by each endpoint are concatenated as byte vectors.
+ These parameters include the parameter type, parameter length, and
+ the parameter value, but padding is omitted; all padding MUST be
+ removed from this concatenation before proceeding with further
+ computation of keys. Parameters that were not sent are simply
+ omitted from the concatenation process. The resulting two vectors
+ are called the two key vectors.
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 10]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ From the endpoint pair shared keys and the key vectors, the
+ association shared keys are computed. This is performed by selecting
+ the numerically smaller key vector and concatenating it to the
+ endpoint pair shared key, and then concatenating the numerically
+ larger key vector to that. If the key vectors are equal as numbers
+ but differ in length, then the concatenation order is the endpoint
+ shared key, followed by the shorter key vector, followed by the
+ longer key vector. Otherwise, the key vectors are identical, and may
+ be concatenated to the endpoint pair key in any order. The
+ concatenation is performed on byte vectors, and all numerical
+ comparisons use network byte order to convert the key vectors to a
+ number. The result of the concatenation is the association shared
+ key.
+
+6.2. Sending Authenticated Chunks
+
+ Endpoints MUST send all requested chunks that have been authenticated
+ where this has been requested by the peer. The other chunks MAY be
+ sent whether or not they have been authenticated. If endpoint pair
+ shared keys are used, one of them MUST be selected for
+ authentication.
+
+ To send chunks in an authenticated way, the sender MUST include these
+ chunks after an AUTH chunk. This means that a sender MUST bundle
+ chunks in order to authenticate them.
+
+ If the endpoint has no endpoint pair shared key for the peer, it MUST
+ use Shared Key Identifier zero with an empty endpoint pair shared
+ key. If there are multiple endpoint shared keys the sender selects
+ one and uses the corresponding Shared Key Identifier.
+
+ The sender MUST calculate the Message Authentication Code (MAC) (as
+ described in RFC 2104 [2]) using the hash function H as described by
+ the HMAC Identifier and the shared association key K based on the
+ endpoint pair shared key described by the Shared Key Identifier. The
+ 'data' used for the computation of the AUTH-chunk is given by the
+ AUTH chunk with its HMAC field set to zero (as shown in Figure 6)
+ followed by all the chunks that are placed after the AUTH chunk in
+ the SCTP packet.
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 11]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0x0F | Flags=0 | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Shared Key Identifier | HMAC Identifier |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ \ 0 /
+ / +-------------------------------\
+ | | Padding |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Figure 6
+
+ Please note that all fields are in network byte order and that the
+ field that will contain the complete HMAC is filled with zeroes. The
+ length of the field shown as zero is the length of the HMAC described
+ by the HMAC Identifier. The padding of all chunks being
+ authenticated MUST be included in the HMAC computation.
+
+ The sender fills the HMAC into the HMAC field and sends the packet.
+
+6.3. Receiving Authenticated Chunks
+
+ The receiver has a list of chunk types that it expects to be received
+ only after an AUTH-chunk. This list has been sent to the peer during
+ the association setup. It MUST silently discard these chunks if they
+ are not placed after an AUTH chunk in the packet.
+
+ The receiver MUST use the HMAC algorithm indicated in the HMAC
+ Identifier field. If this algorithm was not specified by the
+ receiver in the HMAC-ALGO parameter in the INIT or INIT-ACK chunk
+ during association setup, the AUTH chunk and all the chunks after it
+ MUST be discarded and an ERROR chunk SHOULD be sent with the error
+ cause defined in Section 4.1.
+
+ If an endpoint with no shared key receives a Shared Key Identifier
+ other than 0, it MUST silently discard all authenticated chunks. If
+ the endpoint has at least one endpoint pair shared key for the peer,
+ it MUST use the key specified by the Shared Key Identifier if a key
+ has been configured for that Shared Key Identifier. If no endpoint
+ pair shared key has been configured for that Shared Key Identifier,
+ all authenticated chunks MUST be silently discarded.
+
+ The receiver now performs the same calculation as described for the
+ sender based on Figure 6. If the result of the calculation is the
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 12]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ same as given in the HMAC field, all the chunks following the AUTH
+ chunk are processed. If the field does not match the result of the
+ calculation, all the chunks following the AUTH chunk MUST be silently
+ discarded.
+
+ It should be noted that if the receiver wants to tear down an
+ association in an authenticated way only, the handling of malformed
+ packets should not result in tearing down the association.
+
+ An SCTP implementation has to maintain state for each SCTP
+ association. In the following, we call this data structure the SCTP
+ transmission control block (STCB).
+
+ When an endpoint requires COOKIE-ECHO chunks to be authenticated,
+ some special procedures have to be followed because the reception of
+ a COOKIE-ECHO chunk might result in the creation of an SCTP
+ association. If a packet arrives containing an AUTH chunk as a first
+ chunk, a COOKIE-ECHO chunk as the second chunk, and possibly more
+ chunks after them, and the receiver does not have an STCB for that
+ packet, then authentication is based on the contents of the COOKIE-
+ ECHO chunk. In this situation, the receiver MUST authenticate the
+ chunks in the packet by using the RANDOM parameters, CHUNKS
+ parameters and HMAC_ALGO parameters obtained from the COOKIE-ECHO
+ chunk, and possibly a local shared secret as inputs to the
+ authentication procedure specified in Section 6.3. If authentication
+ fails, then the packet is discarded. If the authentication is
+ successful, the COOKIE-ECHO and all the chunks after the COOKIE-ECHO
+ MUST be processed. If the receiver has an STCB, it MUST process the
+ AUTH chunk as described above using the STCB from the existing
+ association to authenticate the COOKIE-ECHO chunk and all the chunks
+ after it.
+
+ If the receiver does not find an STCB for a packet containing an AUTH
+ chunk as the first chunk and does not find a COOKIE-ECHO chunk as the
+ second chunk, it MUST use the chunks after the AUTH chunk to look up
+ an existing association. If no association is found, the packet MUST
+ be considered as out of the blue. The out of the blue handling MUST
+ be based on the packet without taking the AUTH chunk into account.
+ If an association is found, it MUST process the AUTH chunk using the
+ STCB from the existing association as described earlier.
+
+ Requiring ABORT chunks and COOKIE-ECHO chunks to be authenticated
+ makes it impossible for an attacker to bring down or restart an
+ association as long as the attacker does not know the association
+ shared key. But it should also be noted that if an endpoint accepts
+ ABORT chunks only in an authenticated way, it may take longer to
+ detect that the peer is no longer available. If an endpoint accepts
+ COOKIE-ECHO chunks only in an authenticated way, the restart
+
+
+
+Tuexen, et al. Standards Track [Page 13]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ procedure does not work, because the restarting endpoint most likely
+ does not know the association shared key of the old association to be
+ restarted. However, if the restarting endpoint does know the old
+ association shared key, he can successfully send the COOKIE-ECHO
+ chunk in a way that it is accepted by the peer by using this old
+ association shared key for the packet containing the AUTH chunk.
+ After this operation, both endpoints have to use the new association
+ shared key.
+
+ If a server has an endpoint pair shared key with some clients, it can
+ request the COOKIE_ECHO chunk to be authenticated and can ensure that
+ only associations from clients with a correct endpoint pair shared
+ key are accepted.
+
+ Furthermore, it is important that the cookie contained in an INIT-ACK
+ chunk and in a COOKIE-ECHO chunk MUST NOT contain any endpoint pair
+ shared keys.
+
+7. Examples
+
+ This section gives examples of message exchanges for association
+ setup.
+
+ The simplest way of using the extension described in this document is
+ given by the following message exchange.
+
+ ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ---------->
+ <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] ---------
+ -------------------- COOKIE-ECHO -------------------->
+ <-------------------- COOKIE-ACK ---------------------
+
+ Please note that the CHUNKS parameter is optional in the INIT and
+ INIT-ACK.
+
+ If the server wants to receive DATA chunks in an authenticated way,
+ the following message exchange is possible:
+
+ ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ---------->
+ <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] ---------
+ --------------- COOKIE-ECHO; AUTH; DATA ------------->
+ <----------------- COOKIE-ACK; SACK ------------------
+
+ Please note that if the endpoint pair shared key depends on the
+ client and the server, and is only known by the upper layer, this
+ message exchange requires an upper layer intervention between the
+ processing of the COOKIE-ECHO chunk and the processing of the AUTH
+ and DATA chunk at the server side. This intervention may be realized
+ by a COMMUNICATION-UP notification followed by the presentation of
+
+
+
+Tuexen, et al. Standards Track [Page 14]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ the endpoint pair shared key by the upper layer to the SCTP stack,
+ see for example Section 10 of RFC 2960 [5]. If this intervention is
+ not possible due to limitations of the API (for example, the socket
+ API), the server might discard the AUTH and DATA chunk, making a
+ retransmission of the DATA chunk necessary. If the same endpoint
+ pair shared key is used for multiple endpoints and does not depend on
+ the client, this intervention might not be necessary.
+
+8. IANA Considerations
+
+ This document (RFC 4895) is the reference for all registrations
+ described in this section. All registrations need to be listed in
+ the document available at SCTP-parameters [9]. The changes are
+ described below.
+
+8.1. A New Chunk Type
+
+ A chunk type for the AUTH chunk has been assigned by IANA. IANA has
+ assigned the value (15), as given in Table 4. An additional line has
+ been added in the "CHUNK TYPES" table of SCTP-parameters [9]:
+
+ CHUNK TYPES
+
+ ID Value Chunk Type Reference
+ ----- ---------- ---------
+ 15 Authentication Chunk (AUTH) [RFC4895]
+
+8.2. Three New Parameter Types
+
+ Parameter types have been assigned for the RANDOM, CHUNKS, and HMAC-
+ ALGO parameter by IANA. The values are as given in Table 1. This
+ required two modifications to the "CHUNK PARAMETER TYPES" tables in
+ SCTP-parameters [9]: the first is the addition of three new lines to
+ the "INIT Chunk Parameter Types" table:
+
+ Chunk Parameter Type Value
+ -------------------- -----
+ Random 32770 (0x8002)
+ Chunk List 32771 (0x8003)
+ Requested HMAC Algorithm Parameter 32772 (0x8004)
+
+ The second required change is the addition of the same three lines to
+ the to the "INIT ACK Chunk Parameter Types" table.
+
+8.3. A New Error Cause
+
+ An error cause for the Unsupported HMAC Identifier error cause has
+ been assigned. The value (261) has been assigned as in Table 3.
+
+
+
+Tuexen, et al. Standards Track [Page 15]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ This requires an additional line of the "CAUSE CODES" table in SCTP-
+ parameters [9]:
+
+ VALUE CAUSE CODE REFERENCE
+ ----- ---------------- ---------
+ 261 (0x0105) Unsupported HMAC Identifier [RFC4895]
+
+8.4. A New Table for HMAC Identifiers
+
+ HMAC Identifiers have to be maintained by IANA. Four initial values
+ have been assigned by IANA as described in Table 2. This required a
+ new table "HMAC IDENTIFIERS" in SCTP-parameters [9]:
+
+ HMAC Identifier Message Digest Algorithm REFERENCE
+ --------------- ------------------------ ---------
+ 0 Reserved [RFC4895]
+ 1 SHA-1 [RFC4895]
+ 2 Reserved [RFC4895]
+ 3 SHA-256 [RFC4895]
+
+ For registering a new HMAC Identifier with IANA, in this table, a
+ request has to be made to assign such a number. This number must be
+ unique and a message digest algorithm usable with the HMAC defined in
+ RFC 2104 [2] MUST be specified. The "Specification Required" policy
+ of RFC 2434 [4] MUST be applied.
+
+9. Security Considerations
+
+ Without using endpoint shared keys, this extension only protects
+ against modification or injection of authenticated chunks by
+ attackers who did not capture the initial handshake setting up the
+ SCTP association.
+
+ If an endpoint pair shared key is used, even a true man in the middle
+ cannot inject chunks, which are required to be authenticated, even if
+ he intercepts the initial message exchange. The endpoint also knows
+ that it is accepting authenticated chunks from a peer who knows the
+ endpoint pair shared key.
+
+ The establishment of endpoint pair shared keys is out of the scope of
+ this document. Other mechanisms can be used, like using TLS or
+ manual configuration.
+
+ When an endpoint accepts COOKIE-ECHO chunks only in an authenticated
+ way the restart procedure does not work. Neither an attacker nor a
+ restarted endpoint not knowing the association shared key can perform
+ an restart. However, if the association shared key is known, it is
+ possible to restart the association.
+
+
+
+Tuexen, et al. Standards Track [Page 16]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ Because SCTP already has a built-in mechanism that handles the
+ reception of duplicated chunks, the presented solution makes use of
+ this functionality and does not provide a method to avoid replay
+ attacks by itself. Of course, this only works within each SCTP
+ association. Therefore, a separate shared key is used for each SCTP
+ association to handle replay attacks covering multiple SCTP
+ associations.
+
+ Each endpoint presenting a list of more than one element in the HMAC-
+ ALGO parameter must be prepared for the peer using the weakest
+ algorithm listed.
+
+ When an endpoint pair uses non-NULL endpoint pair shared keys and one
+ of the endpoints still accepts a NULL key, an attacker who captured
+ the initial handshake can still inject or modify authenticated chunks
+ by using the NULL key.
+
+10. Acknowledgments
+
+ The authors wish to thank David Black, Sascha Grau, Russ Housley,
+ Ivan Arias Rodriguez, Irene Ruengeler, and Magnus Westerlund for
+ their invaluable comments.
+
+11. Normative References
+
+ [1] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+ April 1992.
+
+ [2] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing
+ for Message Authentication", RFC 2104, February 1997.
+
+ [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [4] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA
+ Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.
+
+ [5] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer,
+ H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson,
+ "Stream Control Transmission Protocol", RFC 2960, October 2000.
+
+ [6] Jungmaier, A., Rescorla, E., and M. Tuexen, "Transport Layer
+ Security over Stream Control Transmission Protocol", RFC 3436,
+ December 2002.
+
+ [7] Eastlake, D., Schiller, J., and S. Crocker, "Randomness
+ Requirements for Security", BCP 106, RFC 4086, June 2005.
+
+
+
+
+Tuexen, et al. Standards Track [Page 17]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+ [8] National Institute of Standards and Technology, "Secure Hash
+ Standard", FIPS PUB 180-2, August 2002,
+ <http://csrc.nist.gov/publications/fips/fips180-2/
+ fips180-2.pdf>.
+
+ [9] <http://www.iana.org/assignments/sctp-parameters>
+
+Authors' Addresses
+
+ Michael Tuexen
+ Muenster Univ. of Applied Sciences
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 4875 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ USA
+
+ EMail: rrs@cisco.com
+
+
+ Peter Lei
+ Cisco Systems, Inc.
+ 8735 West Higgins Road
+ Suite 300
+ Chicago, IL 60631
+ USA
+
+ Phone:
+ EMail: peterlei@cisco.com
+
+
+ Eric Rescorla
+ RTFM, Inc.
+ 2064 Edgewood Drive
+ Palo Alto, CA 94303
+ USA
+
+ Phone: +1 650-320-8549
+ EMail: ekr@rtfm.com
+
+
+
+
+Tuexen, et al. Standards Track [Page 18]
+
+RFC 4895 SCTP Authentication Chunk August 2007
+
+
+Full Copyright Statement
+
+ Copyright (C) The IETF Trust (2007).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+ THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Tuexen, et al. Standards Track [Page 19]
+
diff --git a/doc/rfc4960.txt b/doc/rfc4960.txt
new file mode 100644
index 0000000..1c4f9e9
--- /dev/null
+++ b/doc/rfc4960.txt
@@ -0,0 +1,8515 @@
+
+
+
+
+
+
+Network Working Group R. Stewart, Ed.
+Request for Comments: 4960 September 2007
+Obsoletes: 2960, 3309
+Category: Standards Track
+
+
+ Stream Control Transmission Protocol
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ This document obsoletes RFC 2960 and RFC 3309. It describes the
+ Stream Control Transmission Protocol (SCTP). SCTP is designed to
+ transport Public Switched Telephone Network (PSTN) signaling messages
+ over IP networks, but is capable of broader applications.
+
+ SCTP is a reliable transport protocol operating on top of a
+ connectionless packet network such as IP. It offers the following
+ services to its users:
+
+ -- acknowledged error-free non-duplicated transfer of user data,
+
+ -- data fragmentation to conform to discovered path MTU size,
+
+ -- sequenced delivery of user messages within multiple streams, with
+ an option for order-of-arrival delivery of individual user
+ messages,
+
+ -- optional bundling of multiple user messages into a single SCTP
+ packet, and
+
+ -- network-level fault tolerance through supporting of multi-homing
+ at either or both ends of an association.
+
+ The design of SCTP includes appropriate congestion avoidance behavior
+ and resistance to flooding and masquerade attacks.
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 1]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+Table of Contents
+
+ 1. Introduction ....................................................5
+ 1.1. Motivation .................................................5
+ 1.2. Architectural View of SCTP .................................6
+ 1.3. Key Terms ..................................................6
+ 1.4. Abbreviations .............................................10
+ 1.5. Functional View of SCTP ...................................10
+ 1.5.1. Association Startup and Takedown ...................11
+ 1.5.2. Sequenced Delivery within Streams ..................12
+ 1.5.3. User Data Fragmentation ............................12
+ 1.5.4. Acknowledgement and Congestion Avoidance ...........12
+ 1.5.5. Chunk Bundling .....................................13
+ 1.5.6. Packet Validation ..................................13
+ 1.5.7. Path Management ....................................13
+ 1.6. Serial Number Arithmetic ..................................14
+ 1.7. Changes from RFC 2960 .....................................15
+ 2. Conventions ....................................................15
+ 3. SCTP Packet Format .............................................15
+ 3.1. SCTP Common Header Field Descriptions .....................16
+ 3.2. Chunk Field Descriptions ..................................17
+ 3.2.1. Optional/Variable-Length Parameter Format ..........19
+ 3.2.2. Reporting of Unrecognized Parameters ...............21
+ 3.3. SCTP Chunk Definitions ....................................21
+ 3.3.1. Payload Data (DATA) (0) ............................22
+ 3.3.2. Initiation (INIT) (1) ..............................24
+ 3.3.2.1. Optional/Variable-Length
+ Parameters in INIT ........................27
+ 3.3.3. Initiation Acknowledgement (INIT ACK) (2) ..........30
+ 3.3.3.1. Optional or Variable-Length Parameters ....33
+ 3.3.4. Selective Acknowledgement (SACK) (3) ...............34
+ 3.3.5. Heartbeat Request (HEARTBEAT) (4) ..................38
+ 3.3.6. Heartbeat Acknowledgement (HEARTBEAT ACK) (5) ......39
+ 3.3.7. Abort Association (ABORT) (6) ......................40
+ 3.3.8. Shutdown Association (SHUTDOWN) (7) ................41
+ 3.3.9. Shutdown Acknowledgement (SHUTDOWN ACK) (8) ........41
+ 3.3.10. Operation Error (ERROR) (9) .......................42
+ 3.3.10.1. Invalid Stream Identifier (1) ............44
+ 3.3.10.2. Missing Mandatory Parameter (2) ..........44
+ 3.3.10.3. Stale Cookie Error (3) ...................45
+ 3.3.10.4. Out of Resource (4) ......................45
+ 3.3.10.5. Unresolvable Address (5) .................46
+ 3.3.10.6. Unrecognized Chunk Type (6) ..............46
+ 3.3.10.7. Invalid Mandatory Parameter (7) ..........47
+ 3.3.10.8. Unrecognized Parameters (8) ..............47
+ 3.3.10.9. No User Data (9) .........................48
+ 3.3.10.10. Cookie Received While Shutting
+ Down (10) ...............................48
+
+
+
+Stewart Standards Track [Page 2]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 3.3.10.11. Restart of an Association with
+ New Addresses (11) ......................49
+ 3.3.10.12. User-Initiated Abort (12) ...............49
+ 3.3.10.13. Protocol Violation (13) .................50
+ 3.3.11. Cookie Echo (COOKIE ECHO) (10) ....................50
+ 3.3.12. Cookie Acknowledgement (COOKIE ACK) (11) ..........51
+ 3.3.13. Shutdown Complete (SHUTDOWN COMPLETE) (14) ........51
+ 4. SCTP Association State Diagram .................................52
+ 5. Association Initialization .....................................56
+ 5.1. Normal Establishment of an Association ....................56
+ 5.1.1. Handle Stream Parameters ...........................58
+ 5.1.2. Handle Address Parameters ..........................58
+ 5.1.3. Generating State Cookie ............................61
+ 5.1.4. State Cookie Processing ............................62
+ 5.1.5. State Cookie Authentication ........................62
+ 5.1.6. An Example of Normal Association Establishment .....64
+ 5.2. Handle Duplicate or Unexpected INIT, INIT ACK,
+ COOKIE ECHO, and ..........................................65
+ 5.2.1. INIT Received in COOKIE-WAIT or
+ COOKIE-ECHOED State (Item B) .......................66
+ 5.2.2. Unexpected INIT in States Other than
+ CLOSED, COOKIE-ECHOED, .............................66
+ 5.2.3. Unexpected INIT ACK ................................67
+ 5.2.4. Handle a COOKIE ECHO when a TCB Exists .............67
+ 5.2.4.1. An Example of a Association Restart .......69
+ 5.2.5. Handle Duplicate COOKIE-ACK. .......................71
+ 5.2.6. Handle Stale COOKIE Error ..........................71
+ 5.3. Other Initialization Issues ...............................72
+ 5.3.1. Selection of Tag Value .............................72
+ 5.4. Path Verification .........................................72
+ 6. User Data Transfer .............................................73
+ 6.1. Transmission of DATA Chunks ...............................75
+ 6.2. Acknowledgement on Reception of DATA Chunks ...............78
+ 6.2.1. Processing a Received SACK .........................81
+ 6.3. Management of Retransmission Timer ........................83
+ 6.3.1. RTO Calculation ....................................83
+ 6.3.2. Retransmission Timer Rules .........................85
+ 6.3.3. Handle T3-rtx Expiration ...........................86
+ 6.4. Multi-Homed SCTP Endpoints ................................87
+ 6.4.1. Failover from an Inactive Destination Address ......88
+ 6.5. Stream Identifier and Stream Sequence Number ..............88
+ 6.6. Ordered and Unordered Delivery ............................88
+ 6.7. Report Gaps in Received DATA TSNs .........................89
+ 6.8. CRC32c Checksum Calculation ...............................90
+ 6.9. Fragmentation and Reassembly ..............................91
+ 6.10. Bundling .................................................92
+ 7. Congestion Control .............................................93
+ 7.1. SCTP Differences from TCP Congestion Control ..............94
+
+
+
+Stewart Standards Track [Page 3]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 7.2. SCTP Slow-Start and Congestion Avoidance ..................95
+ 7.2.1. Slow-Start .........................................96
+ 7.2.2. Congestion Avoidance ...............................97
+ 7.2.3. Congestion Control .................................98
+ 7.2.4. Fast Retransmit on Gap Reports .....................98
+ 7.3. Path MTU Discovery .......................................100
+ 8. Fault Management ..............................................100
+ 8.1. Endpoint Failure Detection ...............................100
+ 8.2. Path Failure Detection ...................................101
+ 8.3. Path Heartbeat ...........................................102
+ 8.4. Handle "Out of the Blue" Packets .........................104
+ 8.5. Verification Tag .........................................105
+ 8.5.1. Exceptions in Verification Tag Rules ..............105
+ 9. Termination of Association ....................................106
+ 9.1. Abort of an Association ..................................107
+ 9.2. Shutdown of an Association ...............................107
+ 10. Interface with Upper Layer ...................................110
+ 10.1. ULP-to-SCTP .............................................110
+ 10.2. SCTP-to-ULP .............................................120
+ 11. Security Considerations ......................................123
+ 11.1. Security Objectives .....................................123
+ 11.2. SCTP Responses to Potential Threats .....................124
+ 11.2.1. Countering Insider Attacks .......................124
+ 11.2.2. Protecting against Data Corruption in the
+ Network ..........................................124
+ 11.2.3. Protecting Confidentiality .......................124
+ 11.2.4. Protecting against Blind
+ Denial-of-Service Attacks ........................125
+ 11.2.4.1. Flooding ................................125
+ 11.2.4.2. Blind Masquerade ........................126
+ 11.2.4.3. Improper Monopolization of Services .....127
+ 11.3. SCTP Interactions with Firewalls ........................127
+ 11.4. Protection of Non-SCTP-Capable Hosts ....................128
+ 12. Network Management Considerations ............................128
+ 13. Recommended Transmission Control Block (TCB) Parameters ......129
+ 13.1. Parameters Necessary for the SCTP Instance ..............129
+ 13.2. Parameters Necessary per Association (i.e., the TCB) ....129
+ 13.3. Per Transport Address Data ..............................131
+ 13.4. General Parameters Needed ...............................132
+ 14. IANA Considerations ..........................................132
+ 14.1. IETF-defined Chunk Extension ............................132
+ 14.2. IETF-Defined Chunk Parameter Extension ..................133
+ 14.3. IETF-Defined Additional Error Causes ....................133
+ 14.4. Payload Protocol Identifiers ............................134
+ 14.5. Port Numbers Registry ...................................134
+ 15. Suggested SCTP Protocol Parameter Values .....................136
+ 16. Acknowledgements .............................................137
+ Appendix A. Explicit Congestion Notification .....................139
+
+
+
+Stewart Standards Track [Page 4]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Appendix B. CRC32c Checksum Calculation ..........................140
+ Appendix C. ICMP Handling ........................................142
+ References .......................................................149
+ Normative References ..........................................149
+ Informative References ........................................150
+
+1. Introduction
+
+ This section explains the reasoning behind the development of the
+ Stream Control Transmission Protocol (SCTP), the services it offers,
+ and the basic concepts needed to understand the detailed description
+ of the protocol.
+
+ This document obsoletes [RFC2960] and [RFC3309].
+
+1.1. Motivation
+
+ TCP [RFC0793] has performed immense service as the primary means of
+ reliable data transfer in IP networks. However, an increasing number
+ of recent applications have found TCP too limiting, and have
+ incorporated their own reliable data transfer protocol on top of UDP
+ [RFC0768]. The limitations that users have wished to bypass include
+ the following:
+
+ -- TCP provides both reliable data transfer and strict order-of-
+ transmission delivery of data. Some applications need reliable
+ transfer without sequence maintenance, while others would be
+ satisfied with partial ordering of the data. In both of these
+ cases, the head-of-line blocking offered by TCP causes unnecessary
+ delay.
+
+ -- The stream-oriented nature of TCP is often an inconvenience.
+ Applications must add their own record marking to delineate their
+ messages, and must make explicit use of the push facility to
+ ensure that a complete message is transferred in a reasonable
+ time.
+
+ -- The limited scope of TCP sockets complicates the task of providing
+ highly-available data transfer capability using multi-homed hosts.
+
+ -- TCP is relatively vulnerable to denial-of-service attacks, such as
+ SYN attacks.
+
+ Transport of PSTN signaling across the IP network is an application
+ for which all of these limitations of TCP are relevant. While this
+ application directly motivated the development of SCTP, other
+ applications may find SCTP a good match to their requirements.
+
+
+
+
+Stewart Standards Track [Page 5]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+1.2. Architectural View of SCTP
+
+ SCTP is viewed as a layer between the SCTP user application ("SCTP
+ user" for short) and a connectionless packet network service such as
+ IP. The remainder of this document assumes SCTP runs on top of IP.
+ The basic service offered by SCTP is the reliable transfer of user
+ messages between peer SCTP users. It performs this service within
+ the context of an association between two SCTP endpoints. Section 10
+ of this document sketches the API that should exist at the boundary
+ between the SCTP and the SCTP user layers.
+
+ SCTP is connection-oriented in nature, but the SCTP association is a
+ broader concept than the TCP connection. SCTP provides the means for
+ each SCTP endpoint (Section 1.3) to provide the other endpoint
+ (during association startup) with a list of transport addresses
+ (i.e., multiple IP addresses in combination with an SCTP port)
+ through which that endpoint can be reached and from which it will
+ originate SCTP packets. The association spans transfers over all of
+ the possible source/destination combinations that may be generated
+ from each endpoint's lists.
+
+ _____________ _____________
+ | SCTP User | | SCTP User |
+ | Application | | Application |
+ |-------------| |-------------|
+ | SCTP | | SCTP |
+ | Transport | | Transport |
+ | Service | | Service |
+ |-------------| |-------------|
+ | |One or more ---- One or more| |
+ | IP Network |IP address \/ IP address| IP Network |
+ | Service |appearances /\ appearances| Service |
+ |_____________| ---- |_____________|
+
+ SCTP Node A |<-------- Network transport ------->| SCTP Node B
+
+ Figure 1: An SCTP Association
+
+1.3. Key Terms
+
+ Some of the language used to describe SCTP has been introduced in the
+ previous sections. This section provides a consolidated list of the
+ key terms and their definitions.
+
+ o Active destination transport address: A transport address on a
+ peer endpoint that a transmitting endpoint considers available for
+ receiving user messages.
+
+
+
+
+Stewart Standards Track [Page 6]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o Bundling: An optional multiplexing operation, whereby more than
+ one user message may be carried in the same SCTP packet. Each
+ user message occupies its own DATA chunk.
+
+ o Chunk: A unit of information within an SCTP packet, consisting of
+ a chunk header and chunk-specific content.
+
+ o Congestion window (cwnd): An SCTP variable that limits the data,
+ in number of bytes, a sender can send to a particular destination
+ transport address before receiving an acknowledgement.
+
+ o Cumulative TSN Ack Point: The TSN of the last DATA chunk
+ acknowledged via the Cumulative TSN Ack field of a SACK.
+
+ o Idle destination address: An address that has not had user
+ messages sent to it within some length of time, normally the
+ HEARTBEAT interval or greater.
+
+ o Inactive destination transport address: An address that is
+ considered inactive due to errors and unavailable to transport
+ user messages.
+
+ o Message = user message: Data submitted to SCTP by the Upper Layer
+ Protocol (ULP).
+
+ o Message Authentication Code (MAC): An integrity check mechanism
+ based on cryptographic hash functions using a secret key.
+ Typically, message authentication codes are used between two
+ parties that share a secret key in order to validate information
+ transmitted between these parties. In SCTP, it is used by an
+ endpoint to validate the State Cookie information that is returned
+ from the peer in the COOKIE ECHO chunk. The term "MAC" has
+ different meanings in different contexts. SCTP uses this term
+ with the same meaning as in [RFC2104].
+
+ o Network Byte Order: Most significant byte first, a.k.a., big
+ endian.
+
+ o Ordered Message: A user message that is delivered in order with
+ respect to all previous user messages sent within the stream on
+ which the message was sent.
+
+ o Outstanding TSN (at an SCTP endpoint): A TSN (and the associated
+ DATA chunk) that has been sent by the endpoint but for which it
+ has not yet received an acknowledgement.
+
+
+
+
+
+
+Stewart Standards Track [Page 7]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o Path: The route taken by the SCTP packets sent by one SCTP
+ endpoint to a specific destination transport address of its peer
+ SCTP endpoint. Sending to different destination transport
+ addresses does not necessarily guarantee getting separate paths.
+
+ o Primary Path: The primary path is the destination and source
+ address that will be put into a packet outbound to the peer
+ endpoint by default. The definition includes the source address
+ since an implementation MAY wish to specify both destination and
+ source address to better control the return path taken by reply
+ chunks and on which interface the packet is transmitted when the
+ data sender is multi-homed.
+
+ o Receiver Window (rwnd): An SCTP variable a data sender uses to
+ store the most recently calculated receiver window of its peer, in
+ number of bytes. This gives the sender an indication of the space
+ available in the receiver's inbound buffer.
+
+ o SCTP association: A protocol relationship between SCTP endpoints,
+ composed of the two SCTP endpoints and protocol state information
+ including Verification Tags and the currently active set of
+ Transmission Sequence Numbers (TSNs), etc. An association can be
+ uniquely identified by the transport addresses used by the
+ endpoints in the association. Two SCTP endpoints MUST NOT have
+ more than one SCTP association between them at any given time.
+
+ o SCTP endpoint: The logical sender/receiver of SCTP packets. On a
+ multi-homed host, an SCTP endpoint is represented to its peers as
+ a combination of a set of eligible destination transport addresses
+ to which SCTP packets can be sent and a set of eligible source
+ transport addresses from which SCTP packets can be received. All
+ transport addresses used by an SCTP endpoint must use the same
+ port number, but can use multiple IP addresses. A transport
+ address used by an SCTP endpoint must not be used by another SCTP
+ endpoint. In other words, a transport address is unique to an
+ SCTP endpoint.
+
+ o SCTP packet (or packet): The unit of data delivery across the
+ interface between SCTP and the connectionless packet network
+ (e.g., IP). An SCTP packet includes the common SCTP header,
+ possible SCTP control chunks, and user data encapsulated within
+ SCTP DATA chunks.
+
+ o SCTP user application (SCTP user): The logical higher-layer
+ application entity which uses the services of SCTP, also called
+ the Upper-Layer Protocol (ULP).
+
+
+
+
+
+Stewart Standards Track [Page 8]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o Slow-Start Threshold (ssthresh): An SCTP variable. This is the
+ threshold that the endpoint will use to determine whether to
+ perform slow start or congestion avoidance on a particular
+ destination transport address. Ssthresh is in number of bytes.
+
+ o Stream: A unidirectional logical channel established from one to
+ another associated SCTP endpoint, within which all user messages
+ are delivered in sequence except for those submitted to the
+ unordered delivery service.
+
+ Note: The relationship between stream numbers in opposite directions
+ is strictly a matter of how the applications use them. It is the
+ responsibility of the SCTP user to create and manage these
+ correlations if they are so desired.
+
+ o Stream Sequence Number: A 16-bit sequence number used internally
+ by SCTP to ensure sequenced delivery of the user messages within a
+ given stream. One Stream Sequence Number is attached to each user
+ message.
+
+ o Tie-Tags: Two 32-bit random numbers that together make a 64-bit
+ nonce. These tags are used within a State Cookie and TCB so that
+ a newly restarting association can be linked to the original
+ association within the endpoint that did not restart and yet not
+ reveal the true Verification Tags of an existing association.
+
+ o Transmission Control Block (TCB): An internal data structure
+ created by an SCTP endpoint for each of its existing SCTP
+ associations to other SCTP endpoints. TCB contains all the status
+ and operational information for the endpoint to maintain and
+ manage the corresponding association.
+
+ o Transmission Sequence Number (TSN): A 32-bit sequence number used
+ internally by SCTP. One TSN is attached to each chunk containing
+ user data to permit the receiving SCTP endpoint to acknowledge its
+ receipt and detect duplicate deliveries.
+
+ o Transport address: A transport address is traditionally defined by
+ a network-layer address, a transport-layer protocol, and a
+ transport-layer port number. In the case of SCTP running over IP,
+ a transport address is defined by the combination of an IP address
+ and an SCTP port number (where SCTP is the transport protocol).
+
+ o Unacknowledged TSN (at an SCTP endpoint): A TSN (and the
+ associated DATA chunk) that has been received by the endpoint but
+ for which an acknowledgement has not yet been sent. Or in the
+ opposite case, for a packet that has been sent but no
+ acknowledgement has been received.
+
+
+
+Stewart Standards Track [Page 9]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o Unordered Message: Unordered messages are "unordered" with respect
+ to any other message; this includes both other unordered messages
+ as well as other ordered messages. An unordered message might be
+ delivered prior to or later than ordered messages sent on the same
+ stream.
+
+ o User message: The unit of data delivery across the interface
+ between SCTP and its user.
+
+ o Verification Tag: A 32-bit unsigned integer that is randomly
+ generated. The Verification Tag provides a key that allows a
+ receiver to verify that the SCTP packet belongs to the current
+ association and is not an old or stale packet from a previous
+ association.
+
+1.4. Abbreviations
+
+ MAC - Message Authentication Code [RFC2104]
+
+ RTO - Retransmission Timeout
+
+ RTT - Round-Trip Time
+
+ RTTVAR - Round-Trip Time Variation
+
+ SCTP - Stream Control Transmission Protocol
+
+ SRTT - Smoothed RTT
+
+ TCB - Transmission Control Block
+
+ TLV - Type-Length-Value coding format
+
+ TSN - Transmission Sequence Number
+
+ ULP - Upper-Layer Protocol
+
+1.5. Functional View of SCTP
+
+ The SCTP transport service can be decomposed into a number of
+ functions. These are depicted in Figure 2 and explained in the
+ remainder of this section.
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 10]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ SCTP User Application
+
+ -----------------------------------------------------
+ _____________ ____________________
+ | | | Sequenced Delivery |
+ | Association | | within Streams |
+ | | |____________________|
+ | Startup |
+ | | ____________________________
+ | and | | User Data Fragmentation |
+ | | |____________________________|
+ | Takedown |
+ | | ____________________________
+ | | | Acknowledgement |
+ | | | and |
+ | | | Congestion Avoidance |
+ | | |____________________________|
+ | |
+ | | ____________________________
+ | | | Chunk Bundling |
+ | | |____________________________|
+ | |
+ | | ________________________________
+ | | | Packet Validation |
+ | | |________________________________|
+ | |
+ | | ________________________________
+ | | | Path Management |
+ |_____________| |________________________________|
+
+ Figure 2: Functional View of the SCTP Transport Service
+
+1.5.1. Association Startup and Takedown
+
+ An association is initiated by a request from the SCTP user (see the
+ description of the ASSOCIATE (or SEND) primitive in Section 10).
+
+ A cookie mechanism, similar to one described by Karn and Simpson in
+ [RFC2522], is employed during the initialization to provide
+ protection against synchronization attacks. The cookie mechanism
+ uses a four-way handshake, the last two legs of which are allowed to
+ carry user data for fast setup. The startup sequence is described in
+ Section 5 of this document.
+
+ SCTP provides for graceful close (i.e., shutdown) of an active
+ association on request from the SCTP user. See the description of
+ the SHUTDOWN primitive in Section 10. SCTP also allows ungraceful
+ close (i.e., abort), either on request from the user (ABORT
+
+
+
+Stewart Standards Track [Page 11]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ primitive) or as a result of an error condition detected within the
+ SCTP layer. Section 9 describes both the graceful and the ungraceful
+ close procedures.
+
+ SCTP does not support a half-open state (like TCP) wherein one side
+ may continue sending data while the other end is closed. When either
+ endpoint performs a shutdown, the association on each peer will stop
+ accepting new data from its user and only deliver data in queue at
+ the time of the graceful close (see Section 9).
+
+1.5.2. Sequenced Delivery within Streams
+
+ The term "stream" is used in SCTP to refer to a sequence of user
+ messages that are to be delivered to the upper-layer protocol in
+ order with respect to other messages within the same stream. This is
+ in contrast to its usage in TCP, where it refers to a sequence of
+ bytes (in this document, a byte is assumed to be 8 bits).
+
+ The SCTP user can specify at association startup time the number of
+ streams to be supported by the association. This number is
+ negotiated with the remote end (see Section 5.1.1). User messages
+ are associated with stream numbers (SEND, RECEIVE primitives, Section
+ 10). Internally, SCTP assigns a Stream Sequence Number to each
+ message passed to it by the SCTP user. On the receiving side, SCTP
+ ensures that messages are delivered to the SCTP user in sequence
+ within a given stream. However, while one stream may be blocked
+ waiting for the next in-sequence user message, delivery from other
+ streams may proceed.
+
+ SCTP provides a mechanism for bypassing the sequenced delivery
+ service. User messages sent using this mechanism are delivered to
+ the SCTP user as soon as they are received.
+
+1.5.3. User Data Fragmentation
+
+ When needed, SCTP fragments user messages to ensure that the SCTP
+ packet passed to the lower layer conforms to the path MTU. On
+ receipt, fragments are reassembled into complete messages before
+ being passed to the SCTP user.
+
+1.5.4. Acknowledgement and Congestion Avoidance
+
+ SCTP assigns a Transmission Sequence Number (TSN) to each user data
+ fragment or unfragmented message. The TSN is independent of any
+ Stream Sequence Number assigned at the stream level. The receiving
+ end acknowledges all TSNs received, even if there are gaps in the
+ sequence. In this way, reliable delivery is kept functionally
+ separate from sequenced stream delivery.
+
+
+
+Stewart Standards Track [Page 12]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The acknowledgement and congestion avoidance function is responsible
+ for packet retransmission when timely acknowledgement has not been
+ received. Packet retransmission is conditioned by congestion
+ avoidance procedures similar to those used for TCP. See Section 6
+ and Section 7 for a detailed description of the protocol procedures
+ associated with this function.
+
+1.5.5. Chunk Bundling
+
+ As described in Section 3, the SCTP packet as delivered to the lower
+ layer consists of a common header followed by one or more chunks.
+ Each chunk may contain either user data or SCTP control information.
+ The SCTP user has the option to request bundling of more than one
+ user message into a single SCTP packet. The chunk bundling function
+ of SCTP is responsible for assembly of the complete SCTP packet and
+ its disassembly at the receiving end.
+
+ During times of congestion, an SCTP implementation MAY still perform
+ bundling even if the user has requested that SCTP not bundle. The
+ user's disabling of bundling only affects SCTP implementations that
+ may delay a small period of time before transmission (to attempt to
+ encourage bundling). When the user layer disables bundling, this
+ small delay is prohibited but not bundling that is performed during
+ congestion or retransmission.
+
+1.5.6. Packet Validation
+
+ A mandatory Verification Tag field and a 32-bit checksum field (see
+ Appendix B for a description of the CRC32c checksum) are included in
+ the SCTP common header. The Verification Tag value is chosen by each
+ end of the association during association startup. Packets received
+ without the expected Verification Tag value are discarded, as a
+ protection against blind masquerade attacks and against stale SCTP
+ packets from a previous association. The CRC32c checksum should be
+ set by the sender of each SCTP packet to provide additional
+ protection against data corruption in the network. The receiver of
+ an SCTP packet with an invalid CRC32c checksum silently discards the
+ packet.
+
+1.5.7. Path Management
+
+ The sending SCTP user is able to manipulate the set of transport
+ addresses used as destinations for SCTP packets through the
+ primitives described in Section 10. The SCTP path management
+ function chooses the destination transport address for each outgoing
+ SCTP packet based on the SCTP user's instructions and the currently
+ perceived reachability status of the eligible destination set. The
+ path management function monitors reachability through heartbeats
+
+
+
+Stewart Standards Track [Page 13]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ when other packet traffic is inadequate to provide this information
+ and advises the SCTP user when reachability of any far-end transport
+ address changes. The path management function is also responsible
+ for reporting the eligible set of local transport addresses to the
+ far end during association startup, and for reporting the transport
+ addresses returned from the far end to the SCTP user.
+
+ At association startup, a primary path is defined for each SCTP
+ endpoint, and is used for normal sending of SCTP packets.
+
+ On the receiving end, the path management is responsible for
+ verifying the existence of a valid SCTP association to which the
+ inbound SCTP packet belongs before passing it for further processing.
+
+ Note: Path Management and Packet Validation are done at the same
+ time, so although described separately above, in reality they cannot
+ be performed as separate items.
+
+1.6. Serial Number Arithmetic
+
+ It is essential to remember that the actual Transmission Sequence
+ Number space is finite, though very large. This space ranges from 0
+ to 2**32 - 1. Since the space is finite, all arithmetic dealing with
+ Transmission Sequence Numbers must be performed modulo 2**32. This
+ unsigned arithmetic preserves the relationship of sequence numbers as
+ they cycle from 2**32 - 1 to 0 again. There are some subtleties to
+ computer modulo arithmetic, so great care should be taken in
+ programming the comparison of such values. When referring to TSNs,
+ the symbol "=<" means "less than or equal"(modulo 2**32).
+
+ Comparisons and arithmetic on TSNs in this document SHOULD use Serial
+ Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
+
+ An endpoint SHOULD NOT transmit a DATA chunk with a TSN that is more
+ than 2**31 - 1 above the beginning TSN of its current send window.
+ Doing so will cause problems in comparing TSNs.
+
+ Transmission Sequence Numbers wrap around when they reach 2**32 - 1.
+ That is, the next TSN a DATA chunk MUST use after transmitting TSN =
+ 2*32 - 1 is TSN = 0.
+
+ Any arithmetic done on Stream Sequence Numbers SHOULD use Serial
+ Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 16.
+ All other arithmetic and comparisons in this document use normal
+ arithmetic.
+
+
+
+
+
+
+Stewart Standards Track [Page 14]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+1.7. Changes from RFC 2960
+
+ SCTP was originally defined in [RFC2960], which this document
+ obsoletes. Readers interested in the details of the various changes
+ that this document incorporates are asked to consult [RFC4460].
+
+2. Conventions
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [RFC2119].
+
+3. SCTP Packet Format
+
+ An SCTP packet is composed of a common header and chunks. A chunk
+ contains either control information or user data.
+
+ The SCTP packet format is shown below:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Common Header |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk #1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk #n |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Multiple chunks can be bundled into one SCTP packet up to the MTU
+ size, except for the INIT, INIT ACK, and SHUTDOWN COMPLETE chunks.
+ These chunks MUST NOT be bundled with any other chunk in a packet.
+ See Section 6.10 for more details on chunk bundling.
+
+ If a user data message doesn't fit into one SCTP packet it can be
+ fragmented into multiple chunks using the procedure defined in
+ Section 6.9.
+
+ All integer fields in an SCTP packet MUST be transmitted in network
+ byte order, unless otherwise stated.
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 15]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.1. SCTP Common Header Field Descriptions
+
+ SCTP Common Header Format
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Source Port Number | Destination Port Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Verification Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Checksum |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Source Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP sender's port number. It can be used by the
+ receiver in combination with the source IP address, the SCTP
+ destination port, and possibly the destination IP address to
+ identify the association to which this packet belongs. The port
+ number 0 MUST NOT be used.
+
+ Destination Port Number: 16 bits (unsigned integer)
+
+ This is the SCTP port number to which this packet is destined.
+ The receiving host will use this port number to de-multiplex the
+ SCTP packet to the correct receiving endpoint/application. The
+ port number 0 MUST NOT be used.
+
+ Verification Tag: 32 bits (unsigned integer)
+
+ The receiver of this packet uses the Verification Tag to validate
+ the sender of this SCTP packet. On transmit, the value of this
+ Verification Tag MUST be set to the value of the Initiate Tag
+ received from the peer endpoint during the association
+ initialization, with the following exceptions:
+
+ - A packet containing an INIT chunk MUST have a zero Verification
+ Tag.
+
+ - A packet containing a SHUTDOWN COMPLETE chunk with the T bit
+ set MUST have the Verification Tag copied from the packet with
+ the SHUTDOWN ACK chunk.
+
+ - A packet containing an ABORT chunk may have the verification
+ tag copied from the packet that caused the ABORT to be sent.
+ For details see Section 8.4 and Section 8.5.
+
+
+
+
+Stewart Standards Track [Page 16]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ An INIT chunk MUST be the only chunk in the SCTP packet carrying it.
+
+ Checksum: 32 bits (unsigned integer)
+
+ This field contains the checksum of this SCTP packet. Its
+ calculation is discussed in Section 6.8. SCTP uses the CRC32c
+ algorithm as described in Appendix B for calculating the checksum.
+
+3.2. Chunk Field Descriptions
+
+ The figure below illustrates the field format for the chunks to be
+ transmitted in the SCTP packet. Each chunk is formatted with a Chunk
+ Type field, a chunk-specific Flag field, a Chunk Length field, and a
+ Value field.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Chunk Value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Type: 8 bits (unsigned integer)
+
+ This field identifies the type of information contained in the
+ Chunk Value field. It takes a value from 0 to 254. The value of
+ 255 is reserved for future use as an extension field.
+
+ The values of Chunk Types are defined as follows:
+
+ ID Value Chunk Type
+ ----- ----------
+ 0 - Payload Data (DATA)
+ 1 - Initiation (INIT)
+ 2 - Initiation Acknowledgement (INIT ACK)
+ 3 - Selective Acknowledgement (SACK)
+ 4 - Heartbeat Request (HEARTBEAT)
+ 5 - Heartbeat Acknowledgement (HEARTBEAT ACK)
+ 6 - Abort (ABORT)
+ 7 - Shutdown (SHUTDOWN)
+ 8 - Shutdown Acknowledgement (SHUTDOWN ACK)
+ 9 - Operation Error (ERROR)
+ 10 - State Cookie (COOKIE ECHO)
+ 11 - Cookie Acknowledgement (COOKIE ACK)
+
+
+
+
+Stewart Standards Track [Page 17]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 12 - Reserved for Explicit Congestion Notification Echo
+ (ECNE)
+ 13 - Reserved for Congestion Window Reduced (CWR)
+ 14 - Shutdown Complete (SHUTDOWN COMPLETE)
+ 15 to 62 - available
+ 63 - reserved for IETF-defined Chunk Extensions
+ 64 to 126 - available
+ 127 - reserved for IETF-defined Chunk Extensions
+ 128 to 190 - available
+ 191 - reserved for IETF-defined Chunk Extensions
+ 192 to 254 - available
+ 255 - reserved for IETF-defined Chunk Extensions
+
+ Chunk Types are encoded such that the highest-order 2 bits specify
+ the action that must be taken if the processing endpoint does not
+ recognize the Chunk Type.
+
+ 00 - Stop processing this SCTP packet and discard it, do not
+ process any further chunks within it.
+
+ 01 - Stop processing this SCTP packet and discard it, do not
+ process any further chunks within it, and report the
+ unrecognized chunk in an 'Unrecognized Chunk Type'.
+
+ 10 - Skip this chunk and continue processing.
+
+ 11 - Skip this chunk and continue processing, but report in an
+ ERROR chunk using the 'Unrecognized Chunk Type' cause of
+ error.
+
+ Note: The ECNE and CWR chunk types are reserved for future use of
+ Explicit Congestion Notification (ECN); see Appendix A.
+
+ Chunk Flags: 8 bits
+
+ The usage of these bits depends on the Chunk type as given by the
+ Chunk Type field. Unless otherwise specified, they are set to 0
+ on transmit and are ignored on receipt.
+
+ Chunk Length: 16 bits (unsigned integer)
+
+ This value represents the size of the chunk in bytes, including
+ the Chunk Type, Chunk Flags, Chunk Length, and Chunk Value fields.
+ Therefore, if the Chunk Value field is zero-length, the Length
+ field will be set to 4. The Chunk Length field does not count any
+ chunk padding.
+
+
+
+
+
+Stewart Standards Track [Page 18]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Chunks (including Type, Length, and Value fields) are padded out
+ by the sender with all zero bytes to be a multiple of 4 bytes
+ long. This padding MUST NOT be more than 3 bytes in total. The
+ Chunk Length value does not include terminating padding of the
+ chunk. However, it does include padding of any variable-length
+ parameter except the last parameter in the chunk. The receiver
+ MUST ignore the padding.
+
+ Note: A robust implementation should accept the chunk whether or
+ not the final padding has been included in the Chunk Length.
+
+ Chunk Value: variable length
+
+ The Chunk Value field contains the actual information to be
+ transferred in the chunk. The usage and format of this field is
+ dependent on the Chunk Type.
+
+ The total length of a chunk (including Type, Length, and Value
+ fields) MUST be a multiple of 4 bytes. If the length of the chunk is
+ not a multiple of 4 bytes, the sender MUST pad the chunk with all
+ zero bytes, and this padding is not included in the Chunk Length
+ field. The sender MUST NOT pad with more than 3 bytes. The receiver
+ MUST ignore the padding bytes.
+
+ SCTP-defined chunks are described in detail in Section 3.3. The
+ guidelines for IETF-defined chunk extensions can be found in Section
+ 14.1 of this document.
+
+3.2.1. Optional/Variable-Length Parameter Format
+
+ Chunk values of SCTP control chunks consist of a chunk-type-specific
+ header of required fields, followed by zero or more parameters. The
+ optional and variable-length parameters contained in a chunk are
+ defined in a Type-Length-Value format as shown below.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Parameter Value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 19]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Chunk Parameter Type: 16 bits (unsigned integer)
+
+ The Type field is a 16-bit identifier of the type of parameter.
+ It takes a value of 0 to 65534.
+
+ The value of 65535 is reserved for IETF-defined extensions.
+ Values other than those defined in specific SCTP chunk
+ descriptions are reserved for use by IETF.
+
+ Chunk Parameter Length: 16 bits (unsigned integer)
+
+ The Parameter Length field contains the size of the parameter in
+ bytes, including the Parameter Type, Parameter Length, and
+ Parameter Value fields. Thus, a parameter with a zero-length
+ Parameter Value field would have a Length field of 4. The
+ Parameter Length does not include any padding bytes.
+
+ Chunk Parameter Value: variable length
+
+ The Parameter Value field contains the actual information to be
+ transferred in the parameter.
+
+ The total length of a parameter (including Type, Parameter Length,
+ and Value fields) MUST be a multiple of 4 bytes. If the length of
+ the parameter is not a multiple of 4 bytes, the sender pads the
+ parameter at the end (i.e., after the Parameter Value field) with
+ all zero bytes. The length of the padding is not included in the
+ Parameter Length field. A sender MUST NOT pad with more than 3
+ bytes. The receiver MUST ignore the padding bytes.
+
+ The Parameter Types are encoded such that the highest-order 2 bits
+ specify the action that must be taken if the processing endpoint
+ does not recognize the Parameter Type.
+
+ 00 - Stop processing this parameter; do not process any further
+ parameters within this chunk.
+
+ 01 - Stop processing this parameter, do not process any further
+ parameters within this chunk, and report the unrecognized
+ parameter in an 'Unrecognized Parameter', as described in
+ Section 3.2.2.
+
+ 10 - Skip this parameter and continue processing.
+
+ 11 - Skip this parameter and continue processing but report the
+ unrecognized parameter in an 'Unrecognized Parameter', as
+ described in Section 3.2.2.
+
+
+
+
+Stewart Standards Track [Page 20]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Please note that in all four cases, an INIT ACK or COOKIE ECHO chunk
+ is sent. In the 00 or 01 case, the processing of the parameters
+ after the unknown parameter is canceled, but no processing already
+ done is rolled back.
+
+ The actual SCTP parameters are defined in the specific SCTP chunk
+ sections. The rules for IETF-defined parameter extensions are
+ defined in Section 14.2. Note that a parameter type MUST be unique
+ across all chunks. For example, the parameter type '5' is used to
+ represent an IPv4 address (see Section 3.3.2.1). The value '5' then
+ is reserved across all chunks to represent an IPv4 address and MUST
+ NOT be reused with a different meaning in any other chunk.
+
+3.2.2. Reporting of Unrecognized Parameters
+
+ If the receiver of an INIT chunk detects unrecognized parameters and
+ has to report them according to Section 3.2.1, it MUST put the
+ 'Unrecognized Parameter' parameter(s) in the INIT ACK chunk sent in
+ response to the INIT chunk. Note that if the receiver of the INIT
+ chunk is NOT going to establish an association (e.g., due to lack of
+ resources), an 'Unrecognized Parameter' would NOT be included with
+ any ABORT being sent to the sender of the INIT.
+
+ If the receiver of an INIT ACK chunk detects unrecognized parameters
+ and has to report them according to Section 3.2.1, it SHOULD bundle
+ the ERROR chunk containing the 'Unrecognized Parameters' error cause
+ with the COOKIE ECHO chunk sent in response to the INIT ACK chunk.
+ If the receiver of the INIT ACK cannot bundle the COOKIE ECHO chunk
+ with the ERROR chunk, the ERROR chunk MAY be sent separately but not
+ before the COOKIE ACK has been received.
+
+ Note: Any time a COOKIE ECHO is sent in a packet, it MUST be the
+ first chunk.
+
+3.3. SCTP Chunk Definitions
+
+ This section defines the format of the different SCTP chunk types.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 21]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.1. Payload Data (DATA) (0)
+
+ The following format MUST be used for the DATA chunk:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0 | Reserved|U|B|E| Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream Identifier S | Stream Sequence Number n |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Payload Protocol Identifier |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / User Data (seq n of Stream S) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Reserved: 5 bits
+
+ Should be set to all '0's and ignored by the receiver.
+
+ U bit: 1 bit
+
+ The (U)nordered bit, if set to '1', indicates that this is an
+ unordered DATA chunk, and there is no Stream Sequence Number
+ assigned to this DATA chunk. Therefore, the receiver MUST ignore
+ the Stream Sequence Number field.
+
+ After reassembly (if necessary), unordered DATA chunks MUST be
+ dispatched to the upper layer by the receiver without any attempt
+ to reorder.
+
+ If an unordered user message is fragmented, each fragment of the
+ message MUST have its U bit set to '1'.
+
+ B bit: 1 bit
+
+ The (B)eginning fragment bit, if set, indicates the first fragment
+ of a user message.
+
+ E bit: 1 bit
+
+ The (E)nding fragment bit, if set, indicates the last fragment of
+ a user message.
+
+
+
+
+Stewart Standards Track [Page 22]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ An unfragmented user message shall have both the B and E bits set to
+ '1'. Setting both B and E bits to '0' indicates a middle fragment of
+ a multi-fragment user message, as summarized in the following table:
+
+ B E Description
+ ============================================================
+ | 1 0 | First piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 0 0 | Middle piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 0 1 | Last piece of a fragmented user message |
+ +----------------------------------------------------------+
+ | 1 1 | Unfragmented message |
+ ============================================================
+ | Table 1: Fragment Description Flags |
+ ============================================================
+
+ When a user message is fragmented into multiple chunks, the TSNs are
+ used by the receiver to reassemble the message. This means that the
+ TSNs for each fragment of a fragmented user message MUST be strictly
+ sequential.
+
+ Length: 16 bits (unsigned integer)
+
+ This field indicates the length of the DATA chunk in bytes from
+ the beginning of the type field to the end of the User Data field
+ excluding any padding. A DATA chunk with one byte of user data
+ will have Length set to 17 (indicating 17 bytes).
+
+ A DATA chunk with a User Data field of length L will have the
+ Length field set to (16 + L) (indicating 16+L bytes) where L MUST
+ be greater than 0.
+
+ TSN: 32 bits (unsigned integer)
+
+ This value represents the TSN for this DATA chunk. The valid
+ range of TSN is from 0 to 4294967295 (2**32 - 1). TSN wraps back
+ to 0 after reaching 4294967295.
+
+ Stream Identifier S: 16 bits (unsigned integer)
+
+ Identifies the stream to which the following user data belongs.
+
+ Stream Sequence Number n: 16 bits (unsigned integer)
+
+ This value represents the Stream Sequence Number of the following
+ user data within the stream S. Valid range is 0 to 65535.
+
+
+
+
+Stewart Standards Track [Page 23]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ When a user message is fragmented by SCTP for transport, the same
+ Stream Sequence Number MUST be carried in each of the fragments of
+ the message.
+
+ Payload Protocol Identifier: 32 bits (unsigned integer)
+
+ This value represents an application (or upper layer) specified
+ protocol identifier. This value is passed to SCTP by its upper
+ layer and sent to its peer. This identifier is not used by SCTP
+ but can be used by certain network entities, as well as by the
+ peer application, to identify the type of information being
+ carried in this DATA chunk. This field must be sent even in
+ fragmented DATA chunks (to make sure it is available for agents in
+ the middle of the network). Note that this field is NOT touched
+ by an SCTP implementation; therefore, its byte order is NOT
+ necessarily big endian. The upper layer is responsible for any
+ byte order conversions to this field.
+
+ The value 0 indicates that no application identifier is specified
+ by the upper layer for this payload data.
+
+ User Data: variable length
+
+ This is the payload user data. The implementation MUST pad the
+ end of the data to a 4-byte boundary with all-zero bytes. Any
+ padding MUST NOT be included in the Length field. A sender MUST
+ never add more than 3 bytes of padding.
+
+3.3.2. Initiation (INIT) (1)
+
+ This chunk is used to initiate an SCTP association between two
+ endpoints. The format of the INIT chunk is shown below:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 24]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 1 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initiate Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit (a_rwnd) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Outbound Streams | Number of Inbound Streams |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initial TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Optional/Variable-Length Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The INIT chunk contains the following parameters. Unless otherwise
+ noted, each parameter MUST only be included once in the INIT chunk.
+
+ Fixed Parameters Status
+ ----------------------------------------------
+ Initiate Tag Mandatory
+ Advertised Receiver Window Credit Mandatory
+ Number of Outbound Streams Mandatory
+ Number of Inbound Streams Mandatory
+ Initial TSN Mandatory
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ IPv4 Address (Note 1) Optional 5 IPv6 Address
+ (Note 1) Optional 6 Cookie Preservative
+ Optional 9 Reserved for ECN Capable (Note 2) Optional
+ 32768 (0x8000) Host Name Address (Note 3) Optional
+ 11 Supported Address Types (Note 4) Optional 12
+
+ Note 1: The INIT chunks can contain multiple addresses that can be
+ IPv4 and/or IPv6 in any combination.
+
+ Note 2: The ECN Capable field is reserved for future use of Explicit
+ Congestion Notification.
+
+ Note 3: An INIT chunk MUST NOT contain more than one Host Name
+ Address parameter. Moreover, the sender of the INIT MUST NOT combine
+ any other address types with the Host Name Address in the INIT. The
+ receiver of INIT MUST ignore any other address types if the Host Name
+ Address parameter is present in the received INIT chunk.
+
+
+
+Stewart Standards Track [Page 25]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Note 4: This parameter, when present, specifies all the address types
+ the sending endpoint can support. The absence of this parameter
+ indicates that the sending endpoint can support any address type.
+
+ IMPLEMENTATION NOTE: If an INIT chunk is received with known
+ parameters that are not optional parameters of the INIT chunk, then
+ the receiver SHOULD process the INIT chunk and send back an INIT ACK.
+ The receiver of the INIT chunk MAY bundle an ERROR chunk with the
+ COOKIE ACK chunk later. However, restrictive implementations MAY
+ send back an ABORT chunk in response to the INIT chunk.
+
+ The Chunk Flags field in INIT is reserved, and all bits in it should
+ be set to 0 by the sender and ignored by the receiver. The sequence
+ of parameters within an INIT can be processed in any order.
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT (the responding end) records the value of
+ the Initiate Tag parameter. This value MUST be placed into the
+ Verification Tag field of every SCTP packet that the receiver of
+ the INIT transmits within this association.
+
+ The Initiate Tag is allowed to have any value except 0. See
+ Section 5.3.1 for more on the selection of the tag value.
+
+ If the value of the Initiate Tag in a received INIT chunk is found
+ to be 0, the receiver MUST treat it as an error and close the
+ association by transmitting an ABORT.
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This value represents the dedicated buffer space, in number of
+ bytes, the sender of the INIT has reserved in association with
+ this window. During the life of the association, this buffer
+ space SHOULD NOT be lessened (i.e., dedicated buffers taken away
+ from this association); however, an endpoint MAY change the value
+ of a_rwnd it sends in SACK chunks.
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT
+ chunk wishes to create in this association. The value of 0 MUST
+ NOT be used.
+
+ Note: A receiver of an INIT with the OS value set to 0 SHOULD
+ abort the association.
+
+
+
+
+Stewart Standards Track [Page 26]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Number of Inbound Streams (MIS): 16 bits (unsigned integer)
+
+ Defines the maximum number of streams the sender of this INIT
+ chunk allows the peer end to create in this association. The
+ value 0 MUST NOT be used.
+
+ Note: There is no negotiation of the actual number of streams but
+ instead the two endpoints will use the min(requested, offered).
+ See Section 5.1.1 for details.
+
+ Note: A receiver of an INIT with the MIS value of 0 SHOULD abort
+ the association.
+
+ Initial TSN (I-TSN): 32 bits (unsigned integer)
+
+ Defines the initial TSN that the sender will use. The valid range
+ is from 0 to 4294967295. This field MAY be set to the value of
+ the Initiate Tag field.
+
+3.3.2.1. Optional/Variable-Length Parameters in INIT
+
+ The following parameters follow the Type-Length-Value format as
+ defined in Section 3.2.1. Any Type-Length-Value fields MUST come
+ after the fixed-length fields defined in the previous section.
+
+ IPv4 Address Parameter (5)
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 5 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPv4 Address |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ IPv4 Address: 32 bits (unsigned integer)
+
+ Contains an IPv4 address of the sending endpoint. It is binary
+ encoded.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 27]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ IPv6 Address Parameter (6)
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 6 | Length = 20 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ | IPv6 Address |
+ | |
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ IPv6 Address: 128 bits (unsigned integer)
+
+ Contains an IPv6 [RFC2460] address of the sending endpoint. It is
+ binary encoded.
+
+ Note: A sender MUST NOT use an IPv4-mapped IPv6 address [RFC4291],
+ but should instead use an IPv4 Address parameter for an IPv4
+ address.
+
+ Combined with the Source Port Number in the SCTP common header,
+ the value passed in an IPv4 or IPv6 Address parameter indicates a
+ transport address the sender of the INIT will support for the
+ association being initiated. That is, during the life time of
+ this association, this IP address can appear in the source address
+ field of an IP datagram sent from the sender of the INIT, and can
+ be used as a destination address of an IP datagram sent from the
+ receiver of the INIT.
+
+ More than one IP Address parameter can be included in an INIT
+ chunk when the INIT sender is multi-homed. Moreover, a multi-
+ homed endpoint may have access to different types of network;
+ thus, more than one address type can be present in one INIT chunk,
+ i.e., IPv4 and IPv6 addresses are allowed in the same INIT chunk.
+
+ If the INIT contains at least one IP Address parameter, then the
+ source address of the IP datagram containing the INIT chunk and
+ any additional address(es) provided within the INIT can be used as
+ destinations by the endpoint receiving the INIT. If the INIT does
+ not contain any IP Address parameters, the endpoint receiving the
+ INIT MUST use the source address associated with the received IP
+ datagram as its sole destination address for the association.
+
+ Note that not using any IP Address parameters in the INIT and INIT
+ ACK is an alternative to make an association more likely to work
+ across a NAT box.
+
+
+
+Stewart Standards Track [Page 28]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Cookie Preservative (9)
+
+ The sender of the INIT shall use this parameter to suggest to the
+ receiver of the INIT for a longer life-span of the State Cookie.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 9 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Suggested Cookie Life-Span Increment (msec.) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Suggested Cookie Life-Span Increment: 32 bits (unsigned integer)
+
+ This parameter indicates to the receiver how much increment in
+ milliseconds the sender wishes the receiver to add to its default
+ cookie life-span.
+
+ This optional parameter should be added to the INIT chunk by the
+ sender when it reattempts establishing an association with a peer
+ to which its previous attempt of establishing the association
+ failed due to a stale cookie operation error. The receiver MAY
+ choose to ignore the suggested cookie life-span increase for its
+ own security reasons.
+
+ Host Name Address (11)
+
+ The sender of INIT uses this parameter to pass its Host Name (in
+ place of its IP addresses) to its peer. The peer is responsible for
+ resolving the name. Using this parameter might make it more likely
+ for the association to work across a NAT box.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 11 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Host Name /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Host Name: variable length
+
+ This field contains a host name in "host name syntax" per RFC 1123
+ Section 2.1 [RFC1123]. The method for resolving the host name is
+ out of scope of SCTP.
+
+
+
+
+Stewart Standards Track [Page 29]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Note: At least one null terminator is included in the Host Name
+ string and must be included in the length.
+
+ Supported Address Types (12)
+
+ The sender of INIT uses this parameter to list all the address types
+ it can support.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 12 | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Type #1 | Address Type #2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ...... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+
+
+ Address Type: 16 bits (unsigned integer)
+
+ This is filled with the type value of the corresponding address
+ TLV (e.g., IPv4 = 5, IPv6 = 6, Host name = 11).
+
+3.3.3. Initiation Acknowledgement (INIT ACK) (2)
+
+ The INIT ACK chunk is used to acknowledge the initiation of an SCTP
+ association.
+
+ The parameter part of INIT ACK is formatted similarly to the INIT
+ chunk. It uses two extra variable parameters: The State Cookie and
+ the Unrecognized Parameter:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 30]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The format of the INIT ACK chunk is shown below:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 2 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initiate Tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Outbound Streams | Number of Inbound Streams |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Initial TSN |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Optional/Variable-Length Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Initiate Tag: 32 bits (unsigned integer)
+
+ The receiver of the INIT ACK records the value of the Initiate Tag
+ parameter. This value MUST be placed into the Verification Tag
+ field of every SCTP packet that the INIT ACK receiver transmits
+ within this association.
+
+ The Initiate Tag MUST NOT take the value 0. See Section 5.3.1 for
+ more on the selection of the Initiate Tag value.
+
+ If the value of the Initiate Tag in a received INIT ACK chunk is
+ found to be 0, the receiver MUST destroy the association
+ discarding its TCB. The receiver MAY send an ABORT for debugging
+ purpose.
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This value represents the dedicated buffer space, in number of
+ bytes, the sender of the INIT ACK has reserved in association with
+ this window. During the life of the association, this buffer
+ space SHOULD NOT be lessened (i.e., dedicated buffers taken away
+ from this association).
+
+ Number of Outbound Streams (OS): 16 bits (unsigned integer)
+
+ Defines the number of outbound streams the sender of this INIT ACK
+ chunk wishes to create in this association. The value of 0 MUST
+
+
+
+Stewart Standards Track [Page 31]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ NOT be used, and the value MUST NOT be greater than the MIS value
+ sent in the INIT chunk.
+
+ Note: A receiver of an INIT ACK with the OS value set to 0 SHOULD
+ destroy the association discarding its TCB.
+
+ Number of Inbound Streams (MIS): 16 bits (unsigned integer)
+
+ Defines the maximum number of streams the sender of this INIT ACK
+ chunk allows the peer end to create in this association. The
+ value 0 MUST NOT be used.
+
+ Note: There is no negotiation of the actual number of streams but
+ instead the two endpoints will use the min(requested, offered).
+ See Section 5.1.1 for details.
+
+ Note: A receiver of an INIT ACK with the MIS value set to 0 SHOULD
+ destroy the association discarding its TCB.
+
+ Initial TSN (I-TSN): 32 bits (unsigned integer)
+
+ Defines the initial TSN that the INIT ACK sender will use. The
+ valid range is from 0 to 4294967295. This field MAY be set to the
+ value of the Initiate Tag field.
+
+ Fixed Parameters Status
+ ----------------------------------------------
+ Initiate Tag Mandatory
+ Advertised Receiver Window Credit Mandatory
+ Number of Outbound Streams Mandatory
+ Number of Inbound Streams Mandatory
+ Initial TSN Mandatory
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ State Cookie Mandatory 7
+ IPv4 Address (Note 1) Optional 5
+ IPv6 Address (Note 1) Optional 6
+ Unrecognized Parameter Optional 8
+ Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
+ Host Name Address (Note 3) Optional 11
+
+ Note 1: The INIT ACK chunks can contain any number of IP address
+ parameters that can be IPv4 and/or IPv6 in any combination.
+
+ Note 2: The ECN Capable field is reserved for future use of Explicit
+ Congestion Notification.
+
+
+
+
+Stewart Standards Track [Page 32]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Note 3: The INIT ACK chunks MUST NOT contain more than one Host Name
+ Address parameter. Moreover, the sender of the INIT ACK MUST NOT
+ combine any other address types with the Host Name Address in the
+ INIT ACK. The receiver of the INIT ACK MUST ignore any other address
+ types if the Host Name Address parameter is present.
+
+ IMPLEMENTATION NOTE: An implementation MUST be prepared to receive an
+ INIT ACK that is quite large (more than 1500 bytes) due to the
+ variable size of the State Cookie AND the variable address list. For
+ example if a responder to the INIT has 1000 IPv4 addresses it wishes
+ to send, it would need at least 8,000 bytes to encode this in the
+ INIT ACK.
+
+ IMPLEMENTATION NOTE: If an INIT ACK chunk is received with known
+ parameters that are not optional parameters of the INIT ACK chunk,
+ then the receiver SHOULD process the INIT ACK chunk and send back a
+ COOKIE ECHO. The receiver of the INIT ACK chunk MAY bundle an ERROR
+ chunk with the COOKIE ECHO chunk. However, restrictive
+ implementations MAY send back an ABORT chunk in response to the INIT
+ ACK chunk.
+
+ In combination with the Source Port carried in the SCTP common
+ header, each IP Address parameter in the INIT ACK indicates to the
+ receiver of the INIT ACK a valid transport address supported by the
+ sender of the INIT ACK for the life time of the association being
+ initiated.
+
+ If the INIT ACK contains at least one IP Address parameter, then the
+ source address of the IP datagram containing the INIT ACK and any
+ additional address(es) provided within the INIT ACK may be used as
+ destinations by the receiver of the INIT ACK. If the INIT ACK does
+ not contain any IP Address parameters, the receiver of the INIT ACK
+ MUST use the source address associated with the received IP datagram
+ as its sole destination address for the association.
+
+ The State Cookie and Unrecognized Parameters use the Type-Length-
+ Value format as defined in Section 3.2.1 and are described below.
+ The other fields are defined the same as their counterparts in the
+ INIT chunk.
+
+3.3.3.1. Optional or Variable-Length Parameters
+
+ State Cookie
+
+ Parameter Type Value: 7
+
+ Parameter Length: Variable size, depending on size of Cookie.
+
+
+
+
+Stewart Standards Track [Page 33]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Parameter Value:
+
+ This parameter value MUST contain all the necessary state and
+ parameter information required for the sender of this INIT ACK to
+ create the association, along with a Message Authentication Code
+ (MAC). See Section 5.1.3 for details on State Cookie definition.
+
+ Unrecognized Parameter:
+
+ Parameter Type Value: 8
+
+ Parameter Length: Variable size.
+
+ Parameter Value:
+
+ This parameter is returned to the originator of the INIT chunk
+ when the INIT contains an unrecognized parameter that has a value
+ that indicates it should be reported to the sender. This
+ parameter value field will contain unrecognized parameters copied
+ from the INIT chunk complete with Parameter Type, Length, and
+ Value fields.
+
+3.3.4. Selective Acknowledgement (SACK) (3)
+
+ This chunk is sent to the peer endpoint to acknowledge received DATA
+ chunks and to inform the peer endpoint of gaps in the received
+ subsequences of DATA chunks as represented by their TSNs.
+
+ The SACK MUST contain the Cumulative TSN Ack, Advertised Receiver
+ Window Credit (a_rwnd), Number of Gap Ack Blocks, and Number of
+ Duplicate TSNs fields.
+
+ By definition, the value of the Cumulative TSN Ack parameter is the
+ last TSN received before a break in the sequence of received TSNs
+ occurs; the next TSN value following this one has not yet been
+ received at the endpoint sending the SACK. This parameter therefore
+ acknowledges receipt of all TSNs less than or equal to its value.
+
+ The handling of a_rwnd by the receiver of the SACK is discussed in
+ detail in Section 6.2.1.
+
+ The SACK also contains zero or more Gap Ack Blocks. Each Gap Ack
+ Block acknowledges a subsequence of TSNs received following a break
+ in the sequence of received TSNs. By definition, all TSNs
+ acknowledged by Gap Ack Blocks are greater than the value of the
+ Cumulative TSN Ack.
+
+
+
+
+
+Stewart Standards Track [Page 34]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 3 |Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cumulative TSN Ack |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Advertised Receiver Window Credit (a_rwnd) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = X |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Gap Ack Block #1 Start | Gap Ack Block #1 End |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Gap Ack Block #N Start | Gap Ack Block #N End |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Duplicate TSN 1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / /
+ \ ... \
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Duplicate TSN X |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to all '0's on transmit and ignored on receipt.
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last DATA chunk received in
+ sequence before a gap. In the case where no DATA chunk has been
+ received, this value is set to the peer's Initial TSN minus one.
+
+ Advertised Receiver Window Credit (a_rwnd): 32 bits (unsigned
+ integer)
+
+ This field indicates the updated receive buffer space in bytes of
+ the sender of this SACK; see Section 6.2.1 for details.
+
+ Number of Gap Ack Blocks: 16 bits (unsigned integer)
+
+ Indicates the number of Gap Ack Blocks included in this SACK.
+
+
+
+
+Stewart Standards Track [Page 35]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Number of Duplicate TSNs: 16 bit
+
+ This field contains the number of duplicate TSNs the endpoint has
+ received. Each duplicate TSN is listed following the Gap Ack
+ Block list.
+
+ Gap Ack Blocks:
+
+ These fields contain the Gap Ack Blocks. They are repeated for
+ each Gap Ack Block up to the number of Gap Ack Blocks defined in
+ the Number of Gap Ack Blocks field. All DATA chunks with TSNs
+ greater than or equal to (Cumulative TSN Ack + Gap Ack Block
+ Start) and less than or equal to (Cumulative TSN Ack + Gap Ack
+ Block End) of each Gap Ack Block are assumed to have been received
+ correctly.
+
+ Gap Ack Block Start: 16 bits (unsigned integer)
+
+ Indicates the Start offset TSN for this Gap Ack Block. To
+ calculate the actual TSN number the Cumulative TSN Ack is added to
+ this offset number. This calculated TSN identifies the first TSN
+ in this Gap Ack Block that has been received.
+
+ Gap Ack Block End: 16 bits (unsigned integer)
+
+ Indicates the End offset TSN for this Gap Ack Block. To calculate
+ the actual TSN number, the Cumulative TSN Ack is added to this
+ offset number. This calculated TSN identifies the TSN of the last
+ DATA chunk received in this Gap Ack Block.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 36]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ For example, assume that the receiver has the following DATA chunks
+ newly arrived at the time when it decides to send a Selective ACK,
+
+ ----------
+ | TSN=17 |
+ ----------
+ | | <- still missing
+ ----------
+ | TSN=15 |
+ ----------
+ | TSN=14 |
+ ----------
+ | | <- still missing
+ ----------
+ | TSN=12 |
+ ----------
+ | TSN=11 |
+ ----------
+ | TSN=10 |
+ ----------
+
+ then the parameter part of the SACK MUST be constructed as follows
+ (assuming the new a_rwnd is set to 4660 by the sender):
+
+ +--------------------------------+
+ | Cumulative TSN Ack = 12 |
+ +--------------------------------+
+ | a_rwnd = 4660 |
+ +----------------+---------------+
+ | num of block=2 | num of dup=0 |
+ +----------------+---------------+
+ |block #1 strt=2 |block #1 end=3 |
+ +----------------+---------------+
+ |block #2 strt=5 |block #2 end=5 |
+ +----------------+---------------+
+
+ Duplicate TSN: 32 bits (unsigned integer)
+
+ Indicates the number of times a TSN was received in duplicate
+ since the last SACK was sent. Every time a receiver gets a
+ duplicate TSN (before sending the SACK), it adds it to the list of
+ duplicates. The duplicate count is reinitialized to zero after
+ sending each SACK.
+
+ For example, if a receiver were to get the TSN 19 three times it
+ would list 19 twice in the outbound SACK. After sending the SACK, if
+ it received yet one more TSN 19 it would list 19 as a duplicate once
+ in the next outgoing SACK.
+
+
+
+Stewart Standards Track [Page 37]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.5. Heartbeat Request (HEARTBEAT) (4)
+
+ An endpoint should send this chunk to its peer endpoint to probe the
+ reachability of a particular destination transport address defined in
+ the present association.
+
+ The parameter field contains the Heartbeat Information, which is a
+ variable-length opaque data structure understood only by the sender.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 4 | Chunk Flags | Heartbeat Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Heartbeat Information TLV (Variable-Length) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ Heartbeat Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and the Heartbeat Information field.
+
+ Heartbeat Information: variable length
+
+ Defined as a variable-length parameter using the format described
+ in Section 3.2.1, i.e.:
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ Heartbeat Info Mandatory 1
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Heartbeat Info Type=1 | HB Info Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Sender-Specific Heartbeat Info /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The Sender-Specific Heartbeat Info field should normally include
+ information about the sender's current time when this HEARTBEAT
+
+
+
+Stewart Standards Track [Page 38]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ chunk is sent and the destination transport address to which this
+ HEARTBEAT is sent (see Section 8.3). This information is simply
+ reflected back by the receiver in the HEARTBEAT ACK message (see
+ Section 3.3.6). Note also that the HEARTBEAT message is both for
+ reachability checking and for path verification (see Section 5.4).
+ When a HEARTBEAT chunk is being used for path verification
+ purposes, it MUST hold a 64-bit random nonce.
+
+3.3.6. Heartbeat Acknowledgement (HEARTBEAT ACK) (5)
+
+ An endpoint should send this chunk to its peer endpoint as a response
+ to a HEARTBEAT chunk (see Section 8.3). A HEARTBEAT ACK is always
+ sent to the source IP address of the IP datagram containing the
+ HEARTBEAT chunk to which this ack is responding.
+
+ The parameter field contains a variable-length opaque data structure.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 5 | Chunk Flags | Heartbeat Ack Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / Heartbeat Information TLV (Variable-Length) /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ Heartbeat Ack Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and the Heartbeat Information field.
+
+ Heartbeat Information: variable length
+
+ This field MUST contain the Heartbeat Information parameter of the
+ Heartbeat Request to which this Heartbeat Acknowledgement is
+ responding.
+
+ Variable Parameters Status Type Value
+ -------------------------------------------------------------
+ Heartbeat Info Mandatory 1
+
+
+
+
+
+
+Stewart Standards Track [Page 39]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.7. Abort Association (ABORT) (6)
+
+ The ABORT chunk is sent to the peer of an association to close the
+ association. The ABORT chunk may contain Cause Parameters to inform
+ the receiver about the reason of the abort. DATA chunks MUST NOT be
+ bundled with ABORT. Control chunks (except for INIT, INIT ACK, and
+ SHUTDOWN COMPLETE) MAY be bundled with an ABORT, but they MUST be
+ placed before the ABORT in the SCTP packet or they will be ignored by
+ the receiver.
+
+ If an endpoint receives an ABORT with a format error or no TCB is
+ found, it MUST silently discard it. Moreover, under any
+ circumstances, an endpoint that receives an ABORT MUST NOT respond to
+ that ABORT by sending an ABORT of its own.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 6 |Reserved |T| Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / zero or more Error Causes /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Reserved: 7 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ T bit: 1 bit
+
+ The T bit is set to 0 if the sender filled in the Verification Tag
+ expected by the peer. If the Verification Tag is reflected, the T
+ bit MUST be set to 1. Reflecting means that the sent Verification
+ Tag is the same as the received one.
+
+ Note: Special rules apply to this chunk for verification; please
+ see Section 8.5.1 for details.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and all the Error Cause fields present.
+
+ See Section 3.3.10 for Error Cause definitions.
+
+
+
+
+Stewart Standards Track [Page 40]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.8. Shutdown Association (SHUTDOWN) (7)
+
+ An endpoint in an association MUST use this chunk to initiate a
+ graceful close of the association with its peer. This chunk has the
+ following format.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 7 | Chunk Flags | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cumulative TSN Ack |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Indicates the length of the parameter. Set to 8.
+
+ Cumulative TSN Ack: 32 bits (unsigned integer)
+
+ This parameter contains the TSN of the last chunk received in
+ sequence before any gaps.
+
+ Note: Since the SHUTDOWN message does not contain Gap Ack Blocks,
+ it cannot be used to acknowledge TSNs received out of order. In a
+ SACK, lack of Gap Ack Blocks that were previously included
+ indicates that the data receiver reneged on the associated DATA
+ chunks. Since SHUTDOWN does not contain Gap Ack Blocks, the
+ receiver of the SHUTDOWN shouldn't interpret the lack of a Gap Ack
+ Block as a renege. (See Section 6.2 for information on reneging.)
+
+3.3.9. Shutdown Acknowledgement (SHUTDOWN ACK) (8)
+
+ This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+ chunk at the completion of the shutdown process; see Section 9.2 for
+ details.
+
+ The SHUTDOWN ACK chunk has no parameters.
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 41]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 8 |Chunk Flags | Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+3.3.10. Operation Error (ERROR) (9)
+
+ An endpoint sends this chunk to its peer endpoint to notify it of
+ certain error conditions. It contains one or more error causes. An
+ Operation Error is not considered fatal in and of itself, but may be
+ used with an ABORT chunk to report a fatal condition. It has the
+ following parameters:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 9 | Chunk Flags | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / one or more Error Causes /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the chunk header
+ and all the Error Cause fields present.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 42]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Error causes are defined as variable-length parameters using the
+ format described in Section 3.2.1, that is:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Cause-Specific Information /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Cause Code: 16 bits (unsigned integer)
+
+ Defines the type of error conditions being reported.
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 1 Invalid Stream Identifier
+ 2 Missing Mandatory Parameter
+ 3 Stale Cookie Error
+ 4 Out of Resource
+ 5 Unresolvable Address
+ 6 Unrecognized Chunk Type
+ 7 Invalid Mandatory Parameter
+ 8 Unrecognized Parameters
+ 9 No User Data
+ 10 Cookie Received While Shutting Down
+ 11 Restart of an Association with New Addresses
+ 12 User Initiated Abort
+ 13 Protocol Violation
+
+ Cause Length: 16 bits (unsigned integer)
+
+ Set to the size of the parameter in bytes, including the Cause
+ Code, Cause Length, and Cause-Specific Information fields.
+
+ Cause-Specific Information: variable length
+
+ This field carries the details of the error condition.
+
+ Section 3.3.10.1 - Section 3.3.10.13 define error causes for SCTP.
+ Guidelines for the IETF to define new error cause values are
+ discussed in Section 14.3.
+
+
+
+
+
+
+Stewart Standards Track [Page 43]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.1. Invalid Stream Identifier (1)
+
+ Cause of error
+ ---------------
+
+ Invalid Stream Identifier: Indicates endpoint received a DATA chunk
+ sent to a nonexistent stream.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=1 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Stream Identifier | (Reserved) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Stream Identifier: 16 bits (unsigned integer)
+
+ Contains the Stream Identifier of the DATA chunk received in
+ error.
+
+ Reserved: 16 bits
+
+ This field is reserved. It is set to all 0's on transmit and
+ ignored on receipt.
+
+3.3.10.2. Missing Mandatory Parameter (2)
+
+ Cause of error
+ ---------------
+
+ Missing Mandatory Parameter: Indicates that one or more mandatory TLV
+ parameters are missing in a received INIT or INIT ACK.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=2 | Cause Length=8+N*2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Number of missing params=N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Missing Param Type #1 | Missing Param Type #2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Missing Param Type #N-1 | Missing Param Type #N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Number of Missing params: 32 bits (unsigned integer)
+
+ This field contains the number of parameters contained in the
+ Cause-Specific Information field.
+
+
+
+
+
+Stewart Standards Track [Page 44]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Missing Param Type: 16 bits (unsigned integer)
+
+ Each field will contain the missing mandatory parameter number.
+
+3.3.10.3. Stale Cookie Error (3)
+
+ Cause of error
+ --------------
+
+ Stale Cookie Error: Indicates the receipt of a valid State Cookie
+ that has expired.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=3 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Measure of Staleness (usec.) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Measure of Staleness: 32 bits (unsigned integer)
+
+ This field contains the difference, in microseconds, between the
+ current time and the time the State Cookie expired.
+
+ The sender of this error cause MAY choose to report how long past
+ expiration the State Cookie is by including a non-zero value in
+ the Measure of Staleness field. If the sender does not wish to
+ provide this information, it should set the Measure of Staleness
+ field to the value of zero.
+
+3.3.10.4. Out of Resource (4)
+
+ Cause of error
+ ---------------
+
+ Out of Resource: Indicates that the sender is out of resource. This
+ is usually sent in combination with or within an ABORT.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=4 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 45]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.5. Unresolvable Address (5)
+
+ Cause of error
+ ---------------
+
+ Unresolvable Address: Indicates that the sender is not able to
+ resolve the specified address parameter (e.g., type of address is not
+ supported by the sender). This is usually sent in combination with
+ or within an ABORT.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=5 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unresolvable Address /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unresolvable Address: variable length
+
+ The Unresolvable Address field contains the complete Type, Length,
+ and Value of the address parameter (or Host Name parameter) that
+ contains the unresolvable address or host name.
+
+3.3.10.6. Unrecognized Chunk Type (6)
+
+ Cause of error
+ ---------------
+
+ Unrecognized Chunk Type: This error cause is returned to the
+ originator of the chunk if the receiver does not understand the chunk
+ and the upper bits of the 'Chunk Type' are set to 01 or 11.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=6 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unrecognized Chunk /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unrecognized Chunk: variable length
+
+ The Unrecognized Chunk field contains the unrecognized chunk from
+ the SCTP packet complete with Chunk Type, Chunk Flags, and Chunk
+ Length.
+
+
+
+
+
+
+
+Stewart Standards Track [Page 46]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.7. Invalid Mandatory Parameter (7)
+
+ Cause of error
+ ---------------
+
+ Invalid Mandatory Parameter: This error cause is returned to the
+ originator of an INIT or INIT ACK chunk when one of the mandatory
+ parameters is set to an invalid value.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=7 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.10.8. Unrecognized Parameters (8)
+
+ Cause of error
+ ---------------
+
+ Unrecognized Parameters: This error cause is returned to the
+ originator of the INIT ACK chunk if the receiver does not recognize
+ one or more Optional TLV parameters in the INIT ACK chunk.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=8 | Cause Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Unrecognized Parameters /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Unrecognized Parameters: variable length
+
+ The Unrecognized Parameters field contains the unrecognized
+ parameters copied from the INIT ACK chunk complete with TLV. This
+ error cause is normally contained in an ERROR chunk bundled with
+ the COOKIE ECHO chunk when responding to the INIT ACK, when the
+ sender of the COOKIE ECHO chunk wishes to report unrecognized
+ parameters.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 47]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.9. No User Data (9)
+
+ Cause of error
+ ---------------
+
+ No User Data: This error cause is returned to the originator of a
+
+ DATA chunk if a received DATA chunk has no user data.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=9 | Cause Length=8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / TSN value /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ TSN value: 32 bits (unsigned integer)
+
+ The TSN value field contains the TSN of the DATA chunk received
+ with no user data field.
+
+ This cause code is normally returned in an ABORT chunk (see
+ Section 6.2).
+
+3.3.10.10. Cookie Received While Shutting Down (10)
+
+ Cause of error
+ ---------------
+
+ Cookie Received While Shutting Down: A COOKIE ECHO was received while
+ the endpoint was in the SHUTDOWN-ACK-SENT state. This error is
+ usually returned in an ERROR chunk bundled with the retransmitted
+ SHUTDOWN ACK.
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=10 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 48]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.11. Restart of an Association with New Addresses (11)
+
+ Cause of error
+ --------------
+
+ Restart of an association with new addresses: An INIT was received on
+ an existing association. But the INIT added addresses to the
+ association that were previously NOT part of the association. The
+ new addresses are listed in the error code. This ERROR is normally
+ sent as part of an ABORT refusing the INIT (see Section 5.2).
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=11 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / New Address TLVs /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: Each New Address TLV is an exact copy of the TLV that was found
+ in the INIT chunk that was new, including the Parameter Type and the
+ Parameter Length.
+
+3.3.10.12. User-Initiated Abort (12)
+
+ Cause of error
+ --------------
+
+ This error cause MAY be included in ABORT chunks that are sent
+ because of an upper-layer request. The upper layer can specify an
+ Upper Layer Abort Reason that is transported by SCTP transparently
+ and MAY be delivered to the upper-layer protocol at the peer.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=12 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Upper Layer Abort Reason /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 49]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+3.3.10.13. Protocol Violation (13)
+
+ Cause of error
+ --------------
+
+ This error cause MAY be included in ABORT chunks that are sent
+ because an SCTP endpoint detects a protocol violation of the peer
+ that is not covered by the error causes described in Section 3.3.10.1
+ to Section 3.3.10.12. An implementation MAY provide additional
+ information specifying what kind of protocol violation has been
+ detected.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=13 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Additional Information /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+3.3.11. Cookie Echo (COOKIE ECHO) (10)
+
+ This chunk is used only during the initialization of an association.
+ It is sent by the initiator of an association to its peer to complete
+ the initialization process. This chunk MUST precede any DATA chunk
+ sent within the association, but MAY be bundled with one or more DATA
+ chunks in the same packet.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 10 |Chunk Flags | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ / Cookie /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bit
+
+ Set to 0 on transmit and ignored on receipt.
+
+ Length: 16 bits (unsigned integer)
+
+ Set to the size of the chunk in bytes, including the 4 bytes of
+ the chunk header and the size of the cookie.
+
+
+
+
+
+Stewart Standards Track [Page 50]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Cookie: variable size
+
+ This field must contain the exact cookie received in the State
+ Cookie parameter from the previous INIT ACK.
+
+ An implementation SHOULD make the cookie as small as possible to
+ ensure interoperability.
+
+ Note: A Cookie Echo does NOT contain a State Cookie parameter;
+ instead, the data within the State Cookie's Parameter Value
+ becomes the data within the Cookie Echo's Chunk Value. This
+ allows an implementation to change only the first 2 bytes of the
+ State Cookie parameter to become a COOKIE ECHO chunk.
+
+3.3.12. Cookie Acknowledgement (COOKIE ACK) (11)
+
+ This chunk is used only during the initialization of an association.
+ It is used to acknowledge the receipt of a COOKIE ECHO chunk. This
+ chunk MUST precede any DATA or SACK chunk sent within the
+ association, but MAY be bundled with one or more DATA chunks or SACK
+ chunk's in the same SCTP packet.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 11 |Chunk Flags | Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+3.3.13. Shutdown Complete (SHUTDOWN COMPLETE) (14)
+
+ This chunk MUST be used to acknowledge the receipt of the SHUTDOWN
+ ACK chunk at the completion of the shutdown process; see Section 9.2
+ for details.
+
+ The SHUTDOWN COMPLETE chunk has no parameters.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 14 |Reserved |T| Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Chunk Flags: 8 bits
+
+
+
+
+Stewart Standards Track [Page 51]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Reserved: 7 bits
+
+ Set to 0 on transmit and ignored on receipt.
+
+ T bit: 1 bit
+
+ The T bit is set to 0 if the sender filled in the Verification Tag
+ expected by the peer. If the Verification Tag is reflected, the T
+ bit MUST be set to 1. Reflecting means that the sent Verification
+ Tag is the same as the received one.
+
+ Note: Special rules apply to this chunk for verification, please see
+ Section 8.5.1 for details.
+
+4. SCTP Association State Diagram
+
+ During the life time of an SCTP association, the SCTP endpoint's
+ association progresses from one state to another in response to
+ various events. The events that may potentially advance an
+ association's state include:
+
+ o SCTP user primitive calls, e.g., [ASSOCIATE], [SHUTDOWN], [ABORT],
+
+ o Reception of INIT, COOKIE ECHO, ABORT, SHUTDOWN, etc., control
+ chunks, or
+
+ o Some timeout events.
+
+ The state diagram in the figures below illustrates state changes,
+ together with the causing events and resulting actions. Note that
+ some of the error conditions are not shown in the state diagram.
+ Full descriptions of all special cases are found in the text.
+
+ Note: Chunk names are given in all capital letters, while parameter
+ names have the first letter capitalized, e.g., COOKIE ECHO chunk type
+ vs. State Cookie parameter. If more than one event/message can occur
+ that causes a state transition, it is labeled (A), (B), etc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 52]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ ----- -------- (from any state)
+ / \ / rcv ABORT [ABORT]
+ rcv INIT | | | ---------- or ----------
+ --------------- | v v delete TCB snd ABORT
+ generate Cookie \ +---------+ delete TCB
+ snd INIT ACK ---| CLOSED |
+ +---------+
+ / \ [ASSOCIATE]
+ / \ ---------------
+ | | create TCB
+ | | snd INIT
+ | | strt init timer
+ rcv valid | |
+ COOKIE ECHO | v
+ (1) ---------------- | +------------+
+ create TCB | | COOKIE-WAIT| (2)
+ snd COOKIE ACK | +------------+
+ | |
+ | | rcv INIT ACK
+ | | -----------------
+ | | snd COOKIE ECHO
+ | | stop init timer
+ | | strt cookie timer
+ | v
+ | +--------------+
+ | | COOKIE-ECHOED| (3)
+ | +--------------+
+ | |
+ | | rcv COOKIE ACK
+ | | -----------------
+ | | stop cookie timer
+ v v
+ +---------------+
+ | ESTABLISHED |
+ +---------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 53]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ (from the ESTABLISHED state only)
+ |
+ |
+ /--------+--------\
+ [SHUTDOWN] / \
+ -------------------| |
+ check outstanding | |
+ DATA chunks | |
+ v |
+ +---------+ |
+ |SHUTDOWN-| | rcv SHUTDOWN
+ |PENDING | |------------------
+ +---------+ | check outstanding
+ | | DATA chunks
+ No more outstanding | |
+ ---------------------| |
+ snd SHUTDOWN | |
+ strt shutdown timer | |
+ v v
+ +---------+ +-----------+
+ (4) |SHUTDOWN-| | SHUTDOWN- | (5,6)
+ |SENT | | RECEIVED |
+ +---------+ +-----------+
+ | \ |
+ (A) rcv SHUTDOWN ACK | \ |
+ ----------------------| \ |
+ stop shutdown timer | \rcv:SHUTDOWN |
+ send SHUTDOWN COMPLETE| \ (B) |
+ delete TCB | \ |
+ | \ | No more outstanding
+ | \ |-----------------
+ | \ | send SHUTDOWN ACK
+ (B)rcv SHUTDOWN | \ | strt shutdown timer
+ ----------------------| \ |
+ send SHUTDOWN ACK | \ |
+ start shutdown timer | \ |
+ move to SHUTDOWN- | \ |
+ ACK-SENT | | |
+ | v |
+ | +-----------+
+ | | SHUTDOWN- | (7)
+ | | ACK-SENT |
+ | +----------+-
+ | | (C)rcv SHUTDOWN COMPLETE
+ | |-----------------
+ | | stop shutdown timer
+ | | delete TCB
+ | |
+
+
+
+Stewart Standards Track [Page 54]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ | | (D)rcv SHUTDOWN ACK
+ | |--------------
+ | | stop shutdown timer
+ | | send SHUTDOWN COMPLETE
+ | | delete TCB
+ | |
+ \ +---------+ /
+ \-->| CLOSED |<--/
+ +---------+
+
+ Figure 3: State Transition Diagram of SCTP
+
+ Notes:
+
+ 1) If the State Cookie in the received COOKIE ECHO is invalid (i.e.,
+ failed to pass the integrity check), the receiver MUST silently
+ discard the packet. Or, if the received State Cookie is expired
+ (see Section 5.1.5), the receiver MUST send back an ERROR chunk.
+ In either case, the receiver stays in the CLOSED state.
+
+ 2) If the T1-init timer expires, the endpoint MUST retransmit INIT
+ and restart the T1-init timer without changing state. This MUST
+ be repeated up to 'Max.Init.Retransmits' times. After that, the
+ endpoint MUST abort the initialization process and report the
+ error to the SCTP user.
+
+ 3) If the T1-cookie timer expires, the endpoint MUST retransmit
+ COOKIE ECHO and restart the T1-cookie timer without changing
+ state. This MUST be repeated up to 'Max.Init.Retransmits' times.
+ After that, the endpoint MUST abort the initialization process
+ and report the error to the SCTP user.
+
+ 4) In the SHUTDOWN-SENT state, the endpoint MUST acknowledge any
+ received DATA chunks without delay.
+
+ 5) In the SHUTDOWN-RECEIVED state, the endpoint MUST NOT accept any
+ new send requests from its SCTP user.
+
+ 6) In the SHUTDOWN-RECEIVED state, the endpoint MUST transmit or
+ retransmit data and leave this state when all data in queue is
+ transmitted.
+
+ 7) In the SHUTDOWN-ACK-SENT state, the endpoint MUST NOT accept any
+ new send requests from its SCTP user.
+
+ The CLOSED state is used to indicate that an association is not
+ created (i.e., doesn't exist).
+
+
+
+
+Stewart Standards Track [Page 55]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5. Association Initialization
+
+ Before the first data transmission can take place from one SCTP
+ endpoint ("A") to another SCTP endpoint ("Z"), the two endpoints must
+ complete an initialization process in order to set up an SCTP
+ association between them.
+
+ The SCTP user at an endpoint should use the ASSOCIATE primitive to
+ initialize an SCTP association to another SCTP endpoint.
+
+ IMPLEMENTATION NOTE: From an SCTP user's point of view, an
+ association may be implicitly opened, without an ASSOCIATE primitive
+ (see Section 10.1 B) being invoked, by the initiating endpoint's
+ sending of the first user data to the destination endpoint. The
+ initiating SCTP will assume default values for all mandatory and
+ optional parameters for the INIT/INIT ACK.
+
+ Once the association is established, unidirectional streams are open
+ for data transfer on both ends (see Section 5.1.1).
+
+5.1. Normal Establishment of an Association
+
+ The initialization process consists of the following steps (assuming
+ that SCTP endpoint "A" tries to set up an association with SCTP
+ endpoint "Z" and "Z" accepts the new association):
+
+ A) "A" first sends an INIT chunk to "Z". In the INIT, "A" must
+ provide its Verification Tag (Tag_A) in the Initiate Tag field.
+ Tag_A SHOULD be a random number in the range of 1 to 4294967295
+ (see Section 5.3.1 for Tag value selection). After sending the
+ INIT, "A" starts the T1-init timer and enters the COOKIE-WAIT
+ state.
+
+ B) "Z" shall respond immediately with an INIT ACK chunk. The
+ destination IP address of the INIT ACK MUST be set to the source
+ IP address of the INIT to which this INIT ACK is responding. In
+ the response, besides filling in other parameters, "Z" must set
+ the Verification Tag field to Tag_A, and also provide its own
+ Verification Tag (Tag_Z) in the Initiate Tag field.
+
+ Moreover, "Z" MUST generate and send along with the INIT ACK a
+ State Cookie. See Section 5.1.3 for State Cookie generation.
+
+ Note: After sending out INIT ACK with the State Cookie parameter,
+ "Z" MUST NOT allocate any resources or keep any states for the new
+ association. Otherwise, "Z" will be vulnerable to resource
+ attacks.
+
+
+
+
+Stewart Standards Track [Page 56]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-
+ init timer and leave the COOKIE-WAIT state. "A" shall then send
+ the State Cookie received in the INIT ACK chunk in a COOKIE ECHO
+ chunk, start the T1-cookie timer, and enter the COOKIE-ECHOED
+ state.
+
+ Note: The COOKIE ECHO chunk can be bundled with any pending
+ outbound DATA chunks, but it MUST be the first chunk in the packet
+ and until the COOKIE ACK is returned the sender MUST NOT send any
+ other packets to the peer.
+
+ D) Upon reception of the COOKIE ECHO chunk, endpoint "Z" will reply
+ with a COOKIE ACK chunk after building a TCB and moving to the
+ ESTABLISHED state. A COOKIE ACK chunk may be bundled with any
+ pending DATA chunks (and/or SACK chunks), but the COOKIE ACK chunk
+ MUST be the first chunk in the packet.
+
+ IMPLEMENTATION NOTE: An implementation may choose to send the
+ Communication Up notification to the SCTP user upon reception of a
+ valid COOKIE ECHO chunk.
+
+ E) Upon reception of the COOKIE ACK, endpoint "A" will move from the
+ COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-
+ cookie timer. It may also notify its ULP about the successful
+ establishment of the association with a Communication Up
+ notification (see Section 10).
+
+ An INIT or INIT ACK chunk MUST NOT be bundled with any other chunk.
+ They MUST be the only chunks present in the SCTP packets that carry
+ them.
+
+ An endpoint MUST send the INIT ACK to the IP address from which it
+ received the INIT.
+
+ Note: T1-init timer and T1-cookie timer shall follow the same rules
+ given in Section 6.3.
+
+ If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but
+ decides not to establish the new association due to missing mandatory
+ parameters in the received INIT or INIT ACK, invalid parameter
+ values, or lack of local resources, it SHOULD respond with an ABORT
+ chunk. It SHOULD also specify the cause of abort, such as the type
+ of the missing mandatory parameters, etc., by including the error
+ cause parameters with the ABORT chunk. The Verification Tag field in
+ the common header of the outbound SCTP packet containing the ABORT
+ chunk MUST be set to the Initiate Tag value of the peer.
+
+
+
+
+
+Stewart Standards Track [Page 57]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Note that a COOKIE ECHO chunk that does NOT pass the integrity check
+ is NOT considered an 'invalid parameter' and requires special
+ handling; see Section 5.1.5.
+
+ After the reception of the first DATA chunk in an association the
+ endpoint MUST immediately respond with a SACK to acknowledge the DATA
+ chunk. Subsequent acknowledgements should be done as described in
+ Section 6.2.
+
+ When the TCB is created, each endpoint MUST set its internal
+ Cumulative TSN Ack Point to the value of its transmitted Initial TSN
+ minus one.
+
+ IMPLEMENTATION NOTE: The IP addresses and SCTP port are generally
+ used as the key to find the TCB within an SCTP instance.
+
+5.1.1. Handle Stream Parameters
+
+ In the INIT and INIT ACK chunks, the sender of the chunk MUST
+ indicate the number of outbound streams (OSs) it wishes to have in
+ the association, as well as the maximum inbound streams (MISs) it
+ will accept from the other endpoint.
+
+ After receiving the stream configuration information from the other
+ side, each endpoint MUST perform the following check: If the peer's
+ MIS is less than the endpoint's OS, meaning that the peer is
+ incapable of supporting all the outbound streams the endpoint wants
+ to configure, the endpoint MUST use MIS outbound streams and MAY
+ report any shortage to the upper layer. The upper layer can then
+ choose to abort the association if the resource shortage is
+ unacceptable.
+
+ After the association is initialized, the valid outbound stream
+ identifier range for either endpoint shall be 0 to min(local OS,
+ remote MIS)-1.
+
+5.1.2. Handle Address Parameters
+
+ During the association initialization, an endpoint shall use the
+ following rules to discover and collect the destination transport
+ address(es) of its peer.
+
+ A) If there are no address parameters present in the received INIT or
+ INIT ACK chunk, the endpoint shall take the source IP address from
+ which the chunk arrives and record it, in combination with the
+ SCTP source port number, as the only destination transport address
+ for this peer.
+
+
+
+
+Stewart Standards Track [Page 58]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ B) If there is a Host Name parameter present in the received INIT or
+ INIT ACK chunk, the endpoint shall resolve that host name to a
+ list of IP address(es) and derive the transport address(es) of
+ this peer by combining the resolved IP address(es) with the SCTP
+ source port.
+
+ The endpoint MUST ignore any other IP Address parameters if they
+ are also present in the received INIT or INIT ACK chunk.
+
+ The time at which the receiver of an INIT resolves the host name
+ has potential security implications to SCTP. If the receiver of
+ an INIT resolves the host name upon the reception of the chunk,
+ and the mechanism the receiver uses to resolve the host name
+ involves potential long delay (e.g., DNS query), the receiver may
+ open itself up to resource attacks for the period of time while it
+ is waiting for the name resolution results before it can build the
+ State Cookie and release local resources.
+
+ Therefore, in cases where the name translation involves potential
+ long delay, the receiver of the INIT MUST postpone the name
+ resolution till the reception of the COOKIE ECHO chunk from the
+ peer. In such a case, the receiver of the INIT SHOULD build the
+ State Cookie using the received Host Name (instead of destination
+ transport addresses) and send the INIT ACK to the source IP
+ address from which the INIT was received.
+
+ The receiver of an INIT ACK shall always immediately attempt to
+ resolve the name upon the reception of the chunk.
+
+ The receiver of the INIT or INIT ACK MUST NOT send user data
+ (piggy-backed or stand-alone) to its peer until the host name is
+ successfully resolved.
+
+ If the name resolution is not successful, the endpoint MUST
+ immediately send an ABORT with "Unresolvable Address" error cause
+ to its peer. The ABORT shall be sent to the source IP address
+ from which the last peer packet was received.
+
+ C) If there are only IPv4/IPv6 addresses present in the received INIT
+ or INIT ACK chunk, the receiver MUST derive and record all the
+ transport addresses from the received chunk AND the source IP
+ address that sent the INIT or INIT ACK. The transport addresses
+ are derived by the combination of SCTP source port (from the
+ common header) and the IP Address parameter(s) carried in the INIT
+ or INIT ACK chunk and the source IP address of the IP datagram.
+ The receiver should use only these transport addresses as
+ destination transport addresses when sending subsequent packets to
+ its peer.
+
+
+
+Stewart Standards Track [Page 59]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ D) An INIT or INIT ACK chunk MUST be treated as belonging to an
+ already established association (or one in the process of being
+ established) if the use of any of the valid address parameters
+ contained within the chunk would identify an existing TCB.
+
+ IMPLEMENTATION NOTE: In some cases (e.g., when the implementation
+ doesn't control the source IP address that is used for transmitting),
+ an endpoint might need to include in its INIT or INIT ACK all
+ possible IP addresses from which packets to the peer could be
+ transmitted.
+
+ After all transport addresses are derived from the INIT or INIT ACK
+ chunk using the above rules, the endpoint shall select one of the
+ transport addresses as the initial primary path.
+
+ Note: The INIT ACK MUST be sent to the source address of the INIT.
+
+ The sender of INIT may include a 'Supported Address Types' parameter
+ in the INIT to indicate what types of address are acceptable. When
+ this parameter is present, the receiver of INIT (initiate) MUST
+ either use one of the address types indicated in the Supported
+ Address Types parameter when responding to the INIT, or abort the
+ association with an "Unresolvable Address" error cause if it is
+ unwilling or incapable of using any of the address types indicated by
+ its peer.
+
+ IMPLEMENTATION NOTE: In the case that the receiver of an INIT ACK
+ fails to resolve the address parameter due to an unsupported type, it
+ can abort the initiation process and then attempt a reinitiation by
+ using a 'Supported Address Types' parameter in the new INIT to
+ indicate what types of address it prefers.
+
+ IMPLEMENTATION NOTE: If an SCTP endpoint that only supports either
+ IPv4 or IPv6 receives IPv4 and IPv6 addresses in an INIT or INIT ACK
+ chunk from its peer, it MUST use all the addresses belonging to the
+ supported address family. The other addresses MAY be ignored. The
+ endpoint SHOULD NOT respond with any kind of error indication.
+
+ IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported
+ Address Types' parameter either IPv4 or IPv6, but uses the other
+ family for sending the packet containing the INIT chunk, or if it
+ also lists addresses of the other family in the INIT chunk, then the
+ address family that is not listed in the 'Supported Address Types'
+ parameter SHOULD also be considered as supported by the receiver of
+ the INIT chunk. The receiver of the INIT chunk SHOULD NOT respond
+ with any kind of error indication.
+
+
+
+
+
+Stewart Standards Track [Page 60]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.1.3. Generating State Cookie
+
+ When sending an INIT ACK as a response to an INIT chunk, the sender
+ of INIT ACK creates a State Cookie and sends it in the State Cookie
+ parameter of the INIT ACK. Inside this State Cookie, the sender
+ should include a MAC (see [RFC2104] for an example), a timestamp on
+ when the State Cookie is created, and the lifespan of the State
+ Cookie, along with all the information necessary for it to establish
+ the association.
+
+ The following steps SHOULD be taken to generate the State Cookie:
+
+ 1) Create an association TCB using information from both the
+ received INIT and the outgoing INIT ACK chunk,
+
+ 2) In the TCB, set the creation time to the current time of day, and
+ the lifespan to the protocol parameter 'Valid.Cookie.Life' (see
+ Section 15),
+
+ 3) From the TCB, identify and collect the minimal subset of
+ information needed to re-create the TCB, and generate a MAC using
+ this subset of information and a secret key (see [RFC2104] for an
+ example of generating a MAC), and
+
+ 4) Generate the State Cookie by combining this subset of information
+ and the resultant MAC.
+
+ After sending the INIT ACK with the State Cookie parameter, the
+ sender SHOULD delete the TCB and any other local resource related to
+ the new association, so as to prevent resource attacks.
+
+ The hashing method used to generate the MAC is strictly a private
+ matter for the receiver of the INIT chunk. The use of a MAC is
+ mandatory to prevent denial-of-service attacks. The secret key
+ SHOULD be random ([RFC4086] provides some information on randomness
+ guidelines); it SHOULD be changed reasonably frequently, and the
+ timestamp in the State Cookie MAY be used to determine which key
+ should be used to verify the MAC.
+
+ An implementation SHOULD make the cookie as small as possible to
+ ensure interoperability.
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 61]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.1.4. State Cookie Processing
+
+ When an endpoint (in the COOKIE-WAIT state) receives an INIT ACK
+ chunk with a State Cookie parameter, it MUST immediately send a
+ COOKIE ECHO chunk to its peer with the received State Cookie. The
+ sender MAY also add any pending DATA chunks to the packet after the
+ COOKIE ECHO chunk.
+
+ The endpoint shall also start the T1-cookie timer after sending out
+ the COOKIE ECHO chunk. If the timer expires, the endpoint shall
+ retransmit the COOKIE ECHO chunk and restart the T1-cookie timer.
+ This is repeated until either a COOKIE ACK is received or
+ 'Max.Init.Retransmits' (see Section 15) is reached causing the peer
+ endpoint to be marked unreachable (and thus the association enters
+ the CLOSED state).
+
+5.1.5. State Cookie Authentication
+
+ When an endpoint receives a COOKIE ECHO chunk from another endpoint
+ with which it has no association, it shall take the following
+ actions:
+
+ 1) Compute a MAC using the TCB data carried in the State Cookie and
+ the secret key (note the timestamp in the State Cookie MAY be
+ used to determine which secret key to use). [RFC2104] can be
+ used as a guideline for generating the MAC,
+
+ 2) Authenticate the State Cookie as one that it previously generated
+ by comparing the computed MAC against the one carried in the
+ State Cookie. If this comparison fails, the SCTP packet,
+ including the COOKIE ECHO and any DATA chunks, should be silently
+ discarded,
+
+ 3) Compare the port numbers and the Verification Tag contained
+ within the COOKIE ECHO chunk to the actual port numbers and the
+ Verification Tag within the SCTP common header of the received
+ packet. If these values do not match, the packet MUST be
+ silently discarded.
+
+ 4) Compare the creation timestamp in the State Cookie to the current
+ local time. If the elapsed time is longer than the lifespan
+ carried in the State Cookie, then the packet, including the
+ COOKIE ECHO and any attached DATA chunks, SHOULD be discarded,
+ and the endpoint MUST transmit an ERROR chunk with a "Stale
+ Cookie" error cause to the peer endpoint.
+
+
+
+
+
+
+Stewart Standards Track [Page 62]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 5) If the State Cookie is valid, create an association to the sender
+ of the COOKIE ECHO chunk with the information in the TCB data
+ carried in the COOKIE ECHO and enter the ESTABLISHED state.
+
+ 6) Send a COOKIE ACK chunk to the peer acknowledging receipt of the
+ COOKIE ECHO. The COOKIE ACK MAY be bundled with an outbound DATA
+ chunk or SACK chunk; however, the COOKIE ACK MUST be the first
+ chunk in the SCTP packet.
+
+ 7) Immediately acknowledge any DATA chunk bundled with the COOKIE
+ ECHO with a SACK (subsequent DATA chunk acknowledgement should
+ follow the rules defined in Section 6.2). As mentioned in step
+ 6, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
+ MUST appear first in the SCTP packet.
+
+ If a COOKIE ECHO is received from an endpoint with which the receiver
+ of the COOKIE ECHO has an existing association, the procedures in
+ Section 5.2 should be followed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 63]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.1.6. An Example of Normal Association Establishment
+
+ In the following example, "A" initiates the association and then
+ sends a user message to "Z", then "Z" sends two user messages to "A"
+ later (assuming no bundling or fragmentation occurs):
+
+ Endpoint A Endpoint Z
+ {app sets association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A
+ & other info] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (compose temp TCB and Cookie_Z)
+ /-- INIT ACK [Veri Tag=Tag_A,
+ / I-Tag=Tag_Z,
+ (Cancel T1-init timer) <------/ Cookie_Z, & other info]
+ (destroy temp TCB)
+ COOKIE ECHO [Cookie_Z] ------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (build TCB enter ESTABLISHED
+ state)
+ /---- COOKIE-ACK
+ /
+ (Cancel T1-init timer, <-----/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=0 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /----- SACK [TSN Ack=init
+ / TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+ ...
+ {app sends 2 messages;strm 0}
+ /---- DATA
+ / [TSN=init TSN_Z
+ <--/ Strm=0,Seq=0 & user data 1]
+ SACK [TSN Ack=init TSN_Z, /---- DATA
+ Block=0] --------\ / [TSN=init TSN_Z +1,
+ \/ Strm=0,Seq=1 & user data 2]
+ <------/\
+ \
+ \------>
+
+ Figure 4: INITIATION Example
+
+
+
+
+
+Stewart Standards Track [Page 64]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ If the T1-init timer expires at "A" after the INIT or COOKIE ECHO
+ chunks are sent, the same INIT or COOKIE ECHO chunk with the same
+ Initiate Tag (i.e., Tag_A) or State Cookie shall be retransmitted and
+ the timer restarted. This shall be repeated Max.Init.Retransmits
+ times before "A" considers "Z" unreachable and reports the failure to
+ its upper layer (and thus the association enters the CLOSED state).
+
+ When retransmitting the INIT, the endpoint MUST follow the rules
+ defined in Section 6.3 to determine the proper timer value.
+
+5.2. Handle Duplicate or Unexpected INIT, INIT ACK, COOKIE ECHO, and
+ COOKIE ACK
+
+ During the life time of an association (in one of the possible
+ states), an endpoint may receive from its peer endpoint one of the
+ setup chunks (INIT, INIT ACK, COOKIE ECHO, and COOKIE ACK). The
+ receiver shall treat such a setup chunk as a duplicate and process it
+ as described in this section.
+
+ Note: An endpoint will not receive the chunk unless the chunk was
+ sent to an SCTP transport address and is from an SCTP transport
+ address associated with this endpoint. Therefore, the endpoint
+ processes such a chunk as part of its current association.
+
+ The following scenarios can cause duplicated or unexpected chunks:
+
+ A) The peer has crashed without being detected, restarted itself, and
+ sent out a new INIT chunk trying to restore the association,
+
+ B) Both sides are trying to initialize the association at about the
+ same time,
+
+ C) The chunk is from a stale packet that was used to establish the
+ present association or a past association that is no longer in
+ existence,
+
+ D) The chunk is a false packet generated by an attacker, or
+
+ E) The peer never received the COOKIE ACK and is retransmitting its
+ COOKIE ECHO.
+
+ The rules in the following sections shall be applied in order to
+ identify and correctly handle these cases.
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 65]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.2.1. INIT Received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)
+
+ This usually indicates an initialization collision, i.e., each
+ endpoint is attempting, at about the same time, to establish an
+ association with the other endpoint.
+
+ Upon receipt of an INIT in the COOKIE-WAIT state, an endpoint MUST
+ respond with an INIT ACK using the same parameters it sent in its
+ original INIT chunk (including its Initiate Tag, unchanged). When
+ responding, the endpoint MUST send the INIT ACK back to the same
+ address that the original INIT (sent by this endpoint) was sent.
+
+ Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST
+ respond with an INIT ACK using the same parameters it sent in its
+ original INIT chunk (including its Initiate Tag, unchanged), provided
+ that no NEW address has been added to the forming association. If
+ the INIT message indicates that a new address has been added to the
+ association, then the entire INIT MUST be discarded, and NO changes
+ should be made to the existing association. An ABORT SHOULD be sent
+ in response that MAY include the error 'Restart of an association
+ with new addresses'. The error SHOULD list the addresses that were
+ added to the restarting association.
+
+ When responding in either state (COOKIE-WAIT or COOKIE-ECHOED) with
+ an INIT ACK, the original parameters are combined with those from the
+ newly received INIT chunk. The endpoint shall also generate a State
+ Cookie with the INIT ACK. The endpoint uses the parameters sent in
+ its INIT to calculate the State Cookie.
+
+ After that, the endpoint MUST NOT change its state, the T1-init timer
+ shall be left running, and the corresponding TCB MUST NOT be
+ destroyed. The normal procedures for handling State Cookies when a
+ TCB exists will resolve the duplicate INITs to a single association.
+
+ For an endpoint that is in the COOKIE-ECHOED state, it MUST populate
+ its Tie-Tags within both the association TCB and inside the State
+ Cookie (see Section 5.2.2 for a description of the Tie-Tags).
+
+5.2.2. Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
+ COOKIE-WAIT, and SHUTDOWN-ACK-SENT
+
+ Unless otherwise stated, upon receipt of an unexpected INIT for this
+ association, the endpoint shall generate an INIT ACK with a State
+ Cookie. Before responding, the endpoint MUST check to see if the
+ unexpected INIT adds new addresses to the association. If new
+ addresses are added to the association, the endpoint MUST respond
+ with an ABORT, copying the 'Initiate Tag' of the unexpected INIT into
+ the 'Verification Tag' of the outbound packet carrying the ABORT. In
+
+
+
+Stewart Standards Track [Page 66]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ the ABORT response, the cause of error MAY be set to 'restart of an
+ association with new addresses'. The error SHOULD list the addresses
+ that were added to the restarting association. If no new addresses
+ are added, when responding to the INIT in the outbound INIT ACK, the
+ endpoint MUST copy its current Tie-Tags to a reserved place within
+ the State Cookie and the association's TCB. We shall refer to these
+ locations inside the cookie as the Peer's-Tie-Tag and the Local-Tie-
+ Tag. We will refer to the copy within an association's TCB as the
+ Local Tag and Peer's Tag. The outbound SCTP packet containing this
+ INIT ACK MUST carry a Verification Tag value equal to the Initiate
+ Tag found in the unexpected INIT. And the INIT ACK MUST contain a
+ new Initiate Tag (randomly generated; see Section 5.3.1). Other
+ parameters for the endpoint SHOULD be copied from the existing
+ parameters of the association (e.g., number of outbound streams) into
+ the INIT ACK and cookie.
+
+ After sending out the INIT ACK or ABORT, the endpoint shall take no
+ further actions; i.e., the existing association, including its
+ current state, and the corresponding TCB MUST NOT be changed.
+
+ Note: Only when a TCB exists and the association is not in a COOKIE-
+ WAIT or SHUTDOWN-ACK-SENT state are the Tie-Tags populated with a
+ value other than 0. For a normal association INIT (i.e., the
+ endpoint is in the CLOSED state), the Tie-Tags MUST be set to 0
+ (indicating that no previous TCB existed).
+
+5.2.3. Unexpected INIT ACK
+
+ If an INIT ACK is received by an endpoint in any state other than the
+ COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
+ An unexpected INIT ACK usually indicates the processing of an old or
+ duplicated INIT chunk.
+
+5.2.4. Handle a COOKIE ECHO when a TCB Exists
+
+ When a COOKIE ECHO chunk is received by an endpoint in any state for
+ an existing association (i.e., not in the CLOSED state) the following
+ rules shall be applied:
+
+ 1) Compute a MAC as described in step 1 of Section 5.1.5,
+
+ 2) Authenticate the State Cookie as described in step 2 of Section
+ 5.1.5 (this is case C or D above).
+
+ 3) Compare the timestamp in the State Cookie to the current time.
+ If the State Cookie is older than the lifespan carried in the
+ State Cookie and the Verification Tags contained in the State
+ Cookie do not match the current association's Verification Tags,
+
+
+
+Stewart Standards Track [Page 67]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ the packet, including the COOKIE ECHO and any DATA chunks, should
+ be discarded. The endpoint also MUST transmit an ERROR chunk
+ with a "Stale Cookie" error cause to the peer endpoint (this is
+ case C or D in Section 5.2).
+
+ If both Verification Tags in the State Cookie match the
+ Verification Tags of the current association, consider the State
+ Cookie valid (this is case E in Section 5.2) even if the lifespan
+ is exceeded.
+
+ 4) If the State Cookie proves to be valid, unpack the TCB into a
+ temporary TCB.
+
+ 5) Refer to Table 2 to determine the correct action to be taken.
+
++------------+------------+---------------+--------------+-------------+
+| Local Tag | Peer's Tag | Local-Tie-Tag |Peer's-Tie-Tag| Action/ |
+| | | | | Description |
++------------+------------+---------------+--------------+-------------+
+| X | X | M | M | (A) |
++------------+------------+---------------+--------------+-------------+
+| M | X | A | A | (B) |
++------------+------------+---------------+--------------+-------------+
+| M | 0 | A | A | (B) |
++------------+------------+---------------+--------------+-------------+
+| X | M | 0 | 0 | (C) |
++------------+------------+---------------+--------------+-------------+
+| M | M | A | A | (D) |
++======================================================================+
+| Table 2: Handling of a COOKIE ECHO when a TCB Exists |
++======================================================================+
+
+ Legend:
+
+ X - Tag does not match the existing TCB.
+ M - Tag matches the existing TCB.
+ 0 - No Tie-Tag in cookie (unknown).
+ A - All cases, i.e., M, X, or 0.
+
+ Note: For any case not shown in Table 2, the cookie should be
+ silently discarded.
+
+ Action
+
+ A) In this case, the peer may have restarted. When the endpoint
+ recognizes this potential 'restart', the existing session is
+ treated the same as if it received an ABORT followed by a new
+ COOKIE ECHO with the following exceptions:
+
+
+
+Stewart Standards Track [Page 68]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ - Any SCTP DATA chunks MAY be retained (this is an
+ implementation-specific option).
+
+ - A notification of RESTART SHOULD be sent to the ULP instead of
+ a "COMMUNICATION LOST" notification.
+
+ All the congestion control parameters (e.g., cwnd, ssthresh)
+ related to this peer MUST be reset to their initial values (see
+ Section 6.2.1).
+
+ After this, the endpoint shall enter the ESTABLISHED state.
+
+ If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
+ that the peer has restarted (Action A), it MUST NOT set up a new
+ association but instead resend the SHUTDOWN ACK and send an ERROR
+ chunk with a "Cookie Received While Shutting Down" error cause to
+ its peer.
+
+ B) In this case, both sides may be attempting to start an association
+ at about the same time, but the peer endpoint started its INIT
+ after responding to the local endpoint's INIT. Thus, it may have
+ picked a new Verification Tag, not being aware of the previous tag
+ it had sent this endpoint. The endpoint should stay in or enter
+ the ESTABLISHED state, but it MUST update its peer's Verification
+ Tag from the State Cookie, stop any init or cookie timers that may
+ be running, and send a COOKIE ACK.
+
+ C) In this case, the local endpoint's cookie has arrived late.
+ Before it arrived, the local endpoint sent an INIT and received an
+ INIT ACK and finally sent a COOKIE ECHO with the peer's same tag
+ but a new tag of its own. The cookie should be silently
+ discarded. The endpoint SHOULD NOT change states and should leave
+ any timers running.
+
+ D) When both local and remote tags match, the endpoint should enter
+ the ESTABLISHED state, if it is in the COOKIE-ECHOED state. It
+ should stop any cookie timer that may be running and send a COOKIE
+ ACK.
+
+ Note: The "peer's Verification Tag" is the tag received in the
+ Initiate Tag field of the INIT or INIT ACK chunk.
+
+5.2.4.1. An Example of a Association Restart
+
+ In the following example, "A" initiates the association after a
+ restart has occurred. Endpoint "Z" had no knowledge of the restart
+ until the exchange (i.e., Heartbeats had not yet detected the failure
+ of "A") (assuming no bundling or fragmentation occurs):
+
+
+
+Stewart Standards Track [Page 69]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Endpoint A Endpoint Z
+ <-------------- Association is established---------------------->
+ Tag=Tag_A Tag=Tag_Z
+ <--------------------------------------------------------------->
+ {A crashes and restarts}
+ {app sets up a association with Z}
+ (build TCB)
+ INIT [I-Tag=Tag_A'
+ & other info] --------\
+ (Start T1-init timer) \
+ (Enter COOKIE-WAIT state) \---> (find an existing TCB
+ compose temp TCB and Cookie_Z
+ with Tie-Tags to previous
+ association)
+ /--- INIT ACK [Veri Tag=Tag_A',
+ / I-Tag=Tag_Z',
+ (Cancel T1-init timer) <------/ Cookie_Z[TieTags=
+ Tag_A,Tag_Z
+ & other info]
+ (destroy temp TCB,leave original
+ in place)
+ COOKIE ECHO [Veri=Tag_Z',
+ Cookie_Z
+ Tie=Tag_A,
+ Tag_Z]----------\
+ (Start T1-init timer) \
+ (Enter COOKIE-ECHOED state) \---> (Find existing association,
+ Tie-Tags match old tags,
+ Tags do not match, i.e.,
+ case X X M M above,
+ Announce Restart to ULP
+ and reset association).
+ /---- COOKIE ACK
+ (Cancel T1-init timer, <------/
+ Enter ESTABLISHED state)
+ {app sends 1st user data; strm 0}
+ DATA [TSN=initial TSN_A
+ Strm=0,Seq=0 & user data]--\
+ (Start T3-rtx timer) \
+ \->
+ /--- SACK [TSN Ack=init TSN_A,Block=0]
+ (Cancel T3-rtx timer) <------/
+
+ Figure 5: A Restart Example
+
+
+
+
+
+
+
+Stewart Standards Track [Page 70]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.2.5. Handle Duplicate COOKIE-ACK.
+
+ At any state other than COOKIE-ECHOED, an endpoint should silently
+ discard a received COOKIE ACK chunk.
+
+5.2.6. Handle Stale COOKIE Error
+
+ Receipt of an ERROR chunk with a "Stale Cookie" error cause indicates
+ one of a number of possible events:
+
+ A) The association failed to completely setup before the State Cookie
+ issued by the sender was processed.
+
+ B) An old State Cookie was processed after setup completed.
+
+ C) An old State Cookie is received from someone that the receiver is
+ not interested in having an association with and the ABORT chunk
+ was lost.
+
+ When processing an ERROR chunk with a "Stale Cookie" error cause an
+ endpoint should first examine if an association is in the process of
+ being set up, i.e., the association is in the COOKIE-ECHOED state.
+ In all cases, if the association is not in the COOKIE-ECHOED state,
+ the ERROR chunk should be silently discarded.
+
+ If the association is in the COOKIE-ECHOED state, the endpoint may
+ elect one of the following three alternatives.
+
+ 1) Send a new INIT chunk to the endpoint to generate a new State
+ Cookie and reattempt the setup procedure.
+
+ 2) Discard the TCB and report to the upper layer the inability to
+ set up the association.
+
+ 3) Send a new INIT chunk to the endpoint, adding a Cookie
+ Preservative parameter requesting an extension to the life time
+ of the State Cookie. When calculating the time extension, an
+ implementation SHOULD use the RTT information measured based on
+ the previous COOKIE ECHO / ERROR exchange, and should add no more
+ than 1 second beyond the measured RTT, due to long State Cookie
+ life times making the endpoint more subject to a replay attack.
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 71]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+5.3. Other Initialization Issues
+
+5.3.1. Selection of Tag Value
+
+ Initiate Tag values should be selected from the range of 1 to 2**32 -
+ 1. It is very important that the Initiate Tag value be randomized to
+ help protect against "man in the middle" and "sequence number"
+ attacks. The methods described in [RFC4086] can be used for the
+ Initiate Tag randomization. Careful selection of Initiate Tags is
+ also necessary to prevent old duplicate packets from previous
+ associations being mistakenly processed as belonging to the current
+ association.
+
+ Moreover, the Verification Tag value used by either endpoint in a
+ given association MUST NOT change during the life time of an
+ association. A new Verification Tag value MUST be used each time the
+ endpoint tears down and then reestablishes an association to the same
+ peer.
+
+5.4. Path Verification
+
+ During association establishment, the two peers exchange a list of
+ addresses. In the predominant case, these lists accurately represent
+ the addresses owned by each peer. However, it is possible that a
+ misbehaving peer may supply addresses that it does not own. To
+ prevent this, the following rules are applied to all addresses of the
+ new association:
+
+ 1) Any address passed to the sender of the INIT by its upper layer
+ is automatically considered to be CONFIRMED.
+
+ 2) For the receiver of the COOKIE ECHO, the only CONFIRMED address
+ is the one to which the INIT-ACK was sent.
+
+ 3) All other addresses not covered by rules 1 and 2 are considered
+ UNCONFIRMED and are subject to probing for verification.
+
+ To probe an address for verification, an endpoint will send
+ HEARTBEATs including a 64-bit random nonce and a path indicator (to
+ identify the address that the HEARTBEAT is sent to) within the
+ HEARTBEAT parameter.
+
+ Upon receipt of the HEARTBEAT ACK, a verification is made that the
+ nonce included in the HEARTBEAT parameter is the one sent to the
+ address indicated inside the HEARTBEAT parameter. When this match
+ occurs, the address that the original HEARTBEAT was sent to is now
+ considered CONFIRMED and available for normal data transfer.
+
+
+
+
+Stewart Standards Track [Page 72]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ These probing procedures are started when an association moves to the
+ ESTABLISHED state and are ended when all paths are confirmed.
+
+ In each RTO, a probe may be sent on an active UNCONFIRMED path in an
+ attempt to move it to the CONFIRMED state. If during this probing
+ the path becomes inactive, this rate is lowered to the normal
+ HEARTBEAT rate. At the expiration of the RTO timer, the error
+ counter of any path that was probed but not CONFIRMED is incremented
+ by one and subjected to path failure detection, as defined in Section
+ 8.2. When probing UNCONFIRMED addresses, however, the association
+ overall error count is NOT incremented.
+
+ The number of HEARTBEATS sent at each RTO SHOULD be limited by the
+ HB.Max.Burst parameter. It is an implementation decision as to how
+ to distribute HEARTBEATS to the peer's addresses for path
+ verification.
+
+ Whenever a path is confirmed, an indication MAY be given to the upper
+ layer.
+
+ An endpoint MUST NOT send any chunks to an UNCONFIRMED address, with
+ the following exceptions:
+
+ - A HEARTBEAT including a nonce MAY be sent to an UNCONFIRMED
+ address.
+
+ - A HEARTBEAT ACK MAY be sent to an UNCONFIRMED address.
+
+ - A COOKIE ACK MAY be sent to an UNCONFIRMED address, but it MUST be
+ bundled with a HEARTBEAT including a nonce. An implementation
+ that does NOT support bundling MUST NOT send a COOKIE ACK to an
+ UNCONFIRMED address.
+
+ - A COOKIE ECHO MAY be sent to an UNCONFIRMED address, but it MUST
+ be bundled with a HEARTBEAT including a nonce, and the packet MUST
+ NOT exceed the path MTU. If the implementation does NOT support
+ bundling or if the bundled COOKIE ECHO plus HEARTBEAT (including
+ nonce) would exceed the path MTU, then the implementation MUST NOT
+ send a COOKIE ECHO to an UNCONFIRMED address.
+
+6. User Data Transfer
+
+ Data transmission MUST only happen in the ESTABLISHED, SHUTDOWN-
+ PENDING, and SHUTDOWN-RECEIVED states. The only exception to this is
+ that DATA chunks are allowed to be bundled with an outbound COOKIE
+ ECHO chunk when in the COOKIE-WAIT state.
+
+
+
+
+
+Stewart Standards Track [Page 73]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ DATA chunks MUST only be received according to the rules below in
+ ESTABLISHED, SHUTDOWN-PENDING, and SHUTDOWN-SENT. A DATA chunk
+ received in CLOSED is out of the blue and SHOULD be handled per
+ Section 8.4. A DATA chunk received in any other state SHOULD be
+ discarded.
+
+ A SACK MUST be processed in ESTABLISHED, SHUTDOWN-PENDING, and
+ SHUTDOWN-RECEIVED. An incoming SACK MAY be processed in COOKIE-
+ ECHOED. A SACK in the CLOSED state is out of the blue and SHOULD be
+ processed according to the rules in Section 8.4. A SACK chunk
+ received in any other state SHOULD be discarded.
+
+ An SCTP receiver MUST be able to receive a minimum of 1500 bytes in
+ one SCTP packet. This means that an SCTP endpoint MUST NOT indicate
+ less than 1500 bytes in its initial a_rwnd sent in the INIT or INIT
+ ACK.
+
+ For transmission efficiency, SCTP defines mechanisms for bundling of
+ small user messages and fragmentation of large user messages. The
+ following diagram depicts the flow of user messages through SCTP.
+
+ In this section, the term "data sender" refers to the endpoint that
+ transmits a DATA chunk and the term "data receiver" refers to the
+ endpoint that receives a DATA chunk. A data receiver will transmit
+ SACK chunks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 74]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ +--------------------------+
+ | User Messages |
+ +--------------------------+
+ SCTP user ^ |
+ ==================|==|=======================================
+ | v (1)
+ +------------------+ +--------------------+
+ | SCTP DATA Chunks | |SCTP Control Chunks |
+ +------------------+ +--------------------+
+ ^ | ^ |
+ | v (2) | v (2)
+ +--------------------------+
+ | SCTP packets |
+ +--------------------------+
+ SCTP ^ |
+ ===========================|==|===========================
+ | v
+ Connectionless Packet Transfer Service (e.g., IP)
+
+ Notes:
+
+ 1) When converting user messages into DATA chunks, an endpoint
+ will fragment user messages larger than the current association
+ path MTU into multiple DATA chunks. The data receiver will
+ normally reassemble the fragmented message from DATA chunks
+ before delivery to the user (see Section 6.9 for details).
+
+ 2) Multiple DATA and control chunks may be bundled by the sender
+ into a single SCTP packet for transmission, as long as the
+ final size of the packet does not exceed the current path MTU.
+ The receiver will unbundle the packet back into the original
+ chunks. Control chunks MUST come before DATA chunks in the
+ packet.
+
+ Figure 6: Illustration of User Data Transfer
+
+ The fragmentation and bundling mechanisms, as detailed in Section 6.9
+ and Section 6.10, are OPTIONAL to implement by the data sender, but
+ they MUST be implemented by the data receiver, i.e., an endpoint MUST
+ properly receive and process bundled or fragmented data.
+
+6.1. Transmission of DATA Chunks
+
+ This document is specified as if there is a single retransmission
+ timer per destination transport address, but implementations MAY have
+ a retransmission timer for each DATA chunk.
+
+
+
+
+
+Stewart Standards Track [Page 75]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The following general rules MUST be applied by the data sender for
+ transmission and/or retransmission of outbound DATA chunks:
+
+ A) At any given time, the data sender MUST NOT transmit new data to
+ any destination transport address if its peer's rwnd indicates
+ that the peer has no buffer space (i.e., rwnd is 0; see Section
+ 6.2.1). However, regardless of the value of rwnd (including if it
+ is 0), the data sender can always have one DATA chunk in flight to
+ the receiver if allowed by cwnd (see rule B, below). This rule
+ allows the sender to probe for a change in rwnd that the sender
+ missed due to the SACK's having been lost in transit from the data
+ receiver to the data sender.
+
+ When the receiver's advertised window is zero, this probe is
+ called a zero window probe. Note that a zero window probe SHOULD
+ only be sent when all outstanding DATA chunks have been
+ cumulatively acknowledged and no DATA chunks are in flight. Zero
+ window probing MUST be supported.
+
+ If the sender continues to receive new packets from the receiver
+ while doing zero window probing, the unacknowledged window probes
+ should not increment the error counter for the association or any
+ destination transport address. This is because the receiver MAY
+ keep its window closed for an indefinite time. Refer to Section
+ 6.2 on the receiver behavior when it advertises a zero window.
+ The sender SHOULD send the first zero window probe after 1 RTO
+ when it detects that the receiver has closed its window and SHOULD
+ increase the probe interval exponentially afterwards. Also note
+ that the cwnd SHOULD be adjusted according to Section 7.2.1. Zero
+ window probing does not affect the calculation of cwnd.
+
+ The sender MUST also have an algorithm for sending new DATA chunks
+ to avoid silly window syndrome (SWS) as described in [RFC0813].
+ The algorithm can be similar to the one described in Section
+ 4.2.3.4 of [RFC1122].
+
+ However, regardless of the value of rwnd (including if it is 0),
+ the data sender can always have one DATA chunk in flight to the
+ receiver if allowed by cwnd (see rule B below). This rule allows
+ the sender to probe for a change in rwnd that the sender missed
+ due to the SACK having been lost in transit from the data receiver
+ to the data sender.
+
+ B) At any given time, the sender MUST NOT transmit new data to a
+ given transport address if it has cwnd or more bytes of data
+ outstanding to that transport address.
+
+
+
+
+
+Stewart Standards Track [Page 76]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ C) When the time comes for the sender to transmit, before sending new
+ DATA chunks, the sender MUST first transmit any outstanding DATA
+ chunks that are marked for retransmission (limited by the current
+ cwnd).
+
+ D) When the time comes for the sender to transmit new DATA chunks,
+ the protocol parameter Max.Burst SHOULD be used to limit the
+ number of packets sent. The limit MAY be applied by adjusting
+ cwnd as follows:
+
+ if((flightsize + Max.Burst*MTU) < cwnd) cwnd = flightsize +
+ Max.Burst*MTU
+
+ Or it MAY be applied by strictly limiting the number of packets
+ emitted by the output routine.
+
+ E) Then, the sender can send out as many new DATA chunks as rule A
+ and rule B allow.
+
+ Multiple DATA chunks committed for transmission MAY be bundled in a
+ single packet. Furthermore, DATA chunks being retransmitted MAY be
+ bundled with new DATA chunks, as long as the resulting packet size
+ does not exceed the path MTU. A ULP may request that no bundling is
+ performed, but this should only turn off any delays that an SCTP
+ implementation may be using to increase bundling efficiency. It does
+ not in itself stop all bundling from occurring (i.e., in case of
+ congestion or retransmission).
+
+ Before an endpoint transmits a DATA chunk, if any received DATA
+ chunks have not been acknowledged (e.g., due to delayed ack), the
+ sender should create a SACK and bundle it with the outbound DATA
+ chunk, as long as the size of the final SCTP packet does not exceed
+ the current MTU. See Section 6.2.
+
+ IMPLEMENTATION NOTE: When the window is full (i.e., transmission is
+ disallowed by rule A and/or rule B), the sender MAY still accept send
+ requests from its upper layer, but MUST transmit no more DATA chunks
+ until some or all of the outstanding DATA chunks are acknowledged and
+ transmission is allowed by rule A and rule B again.
+
+ Whenever a transmission or retransmission is made to any address, if
+ the T3-rtx timer of that address is not currently running, the sender
+ MUST start that timer. If the timer for that address is already
+ running, the sender MUST restart the timer if the earliest (i.e.,
+ lowest TSN) outstanding DATA chunk sent to that address is being
+ retransmitted. Otherwise, the data sender MUST NOT restart the
+ timer.
+
+
+
+
+Stewart Standards Track [Page 77]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ When starting or restarting the T3-rtx timer, the timer value must be
+ adjusted according to the timer rules defined in Sections 6.3.2 and
+ 6.3.3.
+
+ Note: The data sender SHOULD NOT use a TSN that is more than 2**31 -
+ 1 above the beginning TSN of the current send window.
+
+6.2. Acknowledgement on Reception of DATA Chunks
+
+ The SCTP endpoint MUST always acknowledge the reception of each valid
+ DATA chunk when the DATA chunk received is inside its receive window.
+
+ When the receiver's advertised window is 0, the receiver MUST drop
+ any new incoming DATA chunk with a TSN larger than the largest TSN
+ received so far. If the new incoming DATA chunk holds a TSN value
+ less than the largest TSN received so far, then the receiver SHOULD
+ drop the largest TSN held for reordering and accept the new incoming
+ DATA chunk. In either case, if such a DATA chunk is dropped, the
+ receiver MUST immediately send back a SACK with the current receive
+ window showing only DATA chunks received and accepted so far. The
+ dropped DATA chunk(s) MUST NOT be included in the SACK, as they were
+ not accepted. The receiver MUST also have an algorithm for
+ advertising its receive window to avoid receiver silly window
+ syndrome (SWS), as described in [RFC0813]. The algorithm can be
+ similar to the one described in Section 4.2.3.3 of [RFC1122].
+
+ The guidelines on delayed acknowledgement algorithm specified in
+ Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an
+ acknowledgement SHOULD be generated for at least every second packet
+ (not every second DATA chunk) received, and SHOULD be generated
+ within 200 ms of the arrival of any unacknowledged DATA chunk. In
+ some situations, it may be beneficial for an SCTP transmitter to be
+ more conservative than the algorithms detailed in this document
+ allow. However, an SCTP transmitter MUST NOT be more aggressive than
+ the following algorithms allow.
+
+ An SCTP receiver MUST NOT generate more than one SACK for every
+ incoming packet, other than to update the offered window as the
+ receiving application consumes new data.
+
+ IMPLEMENTATION NOTE: The maximum delay for generating an
+ acknowledgement may be configured by the SCTP administrator, either
+ statically or dynamically, in order to meet the specific timing
+ requirement of the protocol being carried.
+
+ An implementation MUST NOT allow the maximum delay to be configured
+ to be more than 500 ms. In other words, an implementation MAY lower
+ this value below 500 ms but MUST NOT raise it above 500 ms.
+
+
+
+Stewart Standards Track [Page 78]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Acknowledgements MUST be sent in SACK chunks unless shutdown was
+ requested by the ULP, in which case an endpoint MAY send an
+ acknowledgement in the SHUTDOWN chunk. A SACK chunk can acknowledge
+ the reception of multiple DATA chunks. See Section 3.3.4 for SACK
+ chunk format. In particular, the SCTP endpoint MUST fill in the
+ Cumulative TSN Ack field to indicate the latest sequential TSN (of a
+ valid DATA chunk) it has received. Any received DATA chunks with TSN
+ greater than the value in the Cumulative TSN Ack field are reported
+ in the Gap Ack Block fields. The SCTP endpoint MUST report as many
+ Gap Ack Blocks as can fit in a single SACK chunk limited by the
+ current path MTU.
+
+ Note: The SHUTDOWN chunk does not contain Gap Ack Block fields.
+ Therefore, the endpoint should use a SACK instead of the SHUTDOWN
+ chunk to acknowledge DATA chunks received out of order.
+
+ When a packet arrives with duplicate DATA chunk(s) and with no new
+ DATA chunk(s), the endpoint MUST immediately send a SACK with no
+ delay. If a packet arrives with duplicate DATA chunk(s) bundled with
+ new DATA chunks, the endpoint MAY immediately send a SACK. Normally,
+ receipt of duplicate DATA chunks will occur when the original SACK
+ chunk was lost and the peer's RTO has expired. The duplicate TSN
+ number(s) SHOULD be reported in the SACK as duplicate.
+
+ When an endpoint receives a SACK, it MAY use the duplicate TSN
+ information to determine if SACK loss is occurring. Further use of
+ this data is for future study.
+
+ The data receiver is responsible for maintaining its receive buffers.
+ The data receiver SHOULD notify the data sender in a timely manner of
+ changes in its ability to receive data. How an implementation
+ manages its receive buffers is dependent on many factors (e.g.,
+ operating system, memory management system, amount of memory, etc.).
+ However, the data sender strategy defined in Section 6.2.1 is based
+ on the assumption of receiver operation similar to the following:
+
+ A) At initialization of the association, the endpoint tells the peer
+ how much receive buffer space it has allocated to the association
+ in the INIT or INIT ACK. The endpoint sets a_rwnd to this value.
+
+ B) As DATA chunks are received and buffered, decrement a_rwnd by the
+ number of bytes received and buffered. This is, in effect,
+ closing rwnd at the data sender and restricting the amount of data
+ it can transmit.
+
+
+
+
+
+
+
+Stewart Standards Track [Page 79]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ C) As DATA chunks are delivered to the ULP and released from the
+ receive buffers, increment a_rwnd by the number of bytes delivered
+ to the upper layer. This is, in effect, opening up rwnd on the
+ data sender and allowing it to send more data. The data receiver
+ SHOULD NOT increment a_rwnd unless it has released bytes from its
+ receive buffer. For example, if the receiver is holding
+ fragmented DATA chunks in a reassembly queue, it should not
+ increment a_rwnd.
+
+ D) When sending a SACK, the data receiver SHOULD place the current
+ value of a_rwnd into the a_rwnd field. The data receiver SHOULD
+ take into account that the data sender will not retransmit DATA
+ chunks that are acked via the Cumulative TSN Ack (i.e., will drop
+ from its retransmit queue).
+
+ Under certain circumstances, the data receiver may need to drop DATA
+ chunks that it has received but hasn't released from its receive
+ buffers (i.e., delivered to the ULP). These DATA chunks may have
+ been acked in Gap Ack Blocks. For example, the data receiver may be
+ holding data in its receive buffers while reassembling a fragmented
+ user message from its peer when it runs out of receive buffer space.
+ It may drop these DATA chunks even though it has acknowledged them in
+ Gap Ack Blocks. If a data receiver drops DATA chunks, it MUST NOT
+ include them in Gap Ack Blocks in subsequent SACKs until they are
+ received again via retransmission. In addition, the endpoint should
+ take into account the dropped data when calculating its a_rwnd.
+
+ An endpoint SHOULD NOT revoke a SACK and discard data. Only in
+ extreme circumstances should an endpoint use this procedure (such as
+ out of buffer space). The data receiver should take into account
+ that dropping data that has been acked in Gap Ack Blocks can result
+ in suboptimal retransmission strategies in the data sender and thus
+ in suboptimal performance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 80]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The following example illustrates the use of delayed
+ acknowledgements:
+
+ Endpoint A Endpoint Z
+
+ {App sends 3 messages; strm 0}
+ DATA [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+ (Start T3-rtx timer)
+
+ DATA [TSN=8,Strm=0,Seq=4] ------------> (send ack)
+ /------- SACK [TSN Ack=8,block=0]
+ (cancel T3-rtx timer) <-----/
+
+ DATA [TSN=9,Strm=0,Seq=5] ------------> (ack delayed)
+ (Start T3-rtx timer)
+ ...
+ {App sends 1 message; strm 1}
+ (bundle SACK with DATA)
+ /----- SACK [TSN Ack=9,block=0] \
+ / DATA [TSN=6,Strm=1,Seq=2]
+ (cancel T3-rtx timer) <------/ (Start T3-rtx timer)
+
+ (ack delayed)
+ (send ack)
+ SACK [TSN Ack=6,block=0] -------------> (cancel T3-rtx timer)
+
+ Figure 7: Delayed Acknowledgement Example
+
+ If an endpoint receives a DATA chunk with no user data (i.e., the
+ Length field is set to 16), it MUST send an ABORT with error cause
+ set to "No User Data".
+
+ An endpoint SHOULD NOT send a DATA chunk with no user data part.
+
+6.2.1. Processing a Received SACK
+
+ Each SACK an endpoint receives contains an a_rwnd value. This value
+ represents the amount of buffer space the data receiver, at the time
+ of transmitting the SACK, has left of its total receive buffer space
+ (as specified in the INIT/INIT ACK). Using a_rwnd, Cumulative TSN
+ Ack, and Gap Ack Blocks, the data sender can develop a representation
+ of the peer's receive buffer space.
+
+ One of the problems the data sender must take into account when
+ processing a SACK is that a SACK can be received out of order. That
+ is, a SACK sent by the data receiver can pass an earlier SACK and be
+ received first by the data sender. If a SACK is received out of
+
+
+
+
+Stewart Standards Track [Page 81]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ order, the data sender can develop an incorrect view of the peer's
+ receive buffer space.
+
+ Since there is no explicit identifier that can be used to detect
+ out-of-order SACKs, the data sender must use heuristics to determine
+ if a SACK is new.
+
+ An endpoint SHOULD use the following rules to calculate the rwnd,
+ using the a_rwnd value, the Cumulative TSN Ack, and Gap Ack Blocks in
+ a received SACK.
+
+ A) At the establishment of the association, the endpoint initializes
+ the rwnd to the Advertised Receiver Window Credit (a_rwnd) the
+ peer specified in the INIT or INIT ACK.
+
+ B) Any time a DATA chunk is transmitted (or retransmitted) to a peer,
+ the endpoint subtracts the data size of the chunk from the rwnd of
+ that peer.
+
+ C) Any time a DATA chunk is marked for retransmission, either via
+ T3-rtx timer expiration (Section 6.3.3) or via Fast Retransmit
+ (Section 7.2.4), add the data size of those chunks to the rwnd.
+
+ Note: If the implementation is maintaining a timer on each DATA
+ chunk, then only DATA chunks whose timer expired would be marked
+ for retransmission.
+
+ D) Any time a SACK arrives, the endpoint performs the following:
+
+ i) If Cumulative TSN Ack is less than the Cumulative TSN Ack
+ Point, then drop the SACK. Since Cumulative TSN Ack is
+ monotonically increasing, a SACK whose Cumulative TSN Ack is
+ less than the Cumulative TSN Ack Point indicates an out-of-
+ order SACK.
+
+ ii) Set rwnd equal to the newly received a_rwnd minus the number
+ of bytes still outstanding after processing the Cumulative
+ TSN Ack and the Gap Ack Blocks.
+
+ iii) If the SACK is missing a TSN that was previously acknowledged
+ via a Gap Ack Block (e.g., the data receiver reneged on the
+ data), then consider the corresponding DATA that might be
+ possibly missing: Count one miss indication towards Fast
+ Retransmit as described in Section 7.2.4, and if no
+ retransmit timer is running for the destination address to
+ which the DATA chunk was originally transmitted, then T3-rtx
+ is started for that destination address.
+
+
+
+
+Stewart Standards Track [Page 82]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ iv) If the Cumulative TSN Ack matches or exceeds the Fast
+ Recovery exitpoint (Section 7.2.4), Fast Recovery is exited.
+
+6.3. Management of Retransmission Timer
+
+ An SCTP endpoint uses a retransmission timer T3-rtx to ensure data
+ delivery in the absence of any feedback from its peer. The duration
+ of this timer is referred to as RTO (retransmission timeout).
+
+ When an endpoint's peer is multi-homed, the endpoint will calculate a
+ separate RTO for each different destination transport address of its
+ peer endpoint.
+
+ The computation and management of RTO in SCTP follow closely how TCP
+ manages its retransmission timer. To compute the current RTO, an
+ endpoint maintains two state variables per destination transport
+ address: SRTT (smoothed round-trip time) and RTTVAR (round-trip time
+ variation).
+
+6.3.1. RTO Calculation
+
+ The rules governing the computation of SRTT, RTTVAR, and RTO are as
+ follows:
+
+ C1) Until an RTT measurement has been made for a packet sent to the
+ given destination transport address, set RTO to the protocol
+ parameter 'RTO.Initial'.
+
+ C2) When the first RTT measurement R is made, set
+
+ SRTT <- R,
+
+ RTTVAR <- R/2, and
+
+ RTO <- SRTT + 4 * RTTVAR.
+
+ C3) When a new RTT measurement R' is made, set
+
+ RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'|
+
+ and
+
+ SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
+
+ Note: The value of SRTT used in the update to RTTVAR is its
+ value before updating SRTT itself using the second assignment.
+
+ After the computation, update RTO <- SRTT + 4 * RTTVAR.
+
+
+
+Stewart Standards Track [Page 83]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ C4) When data is in flight and when allowed by rule C5 below, a new
+ RTT measurement MUST be made each round trip. Furthermore, new
+ RTT measurements SHOULD be made no more than once per round trip
+ for a given destination transport address. There are two
+ reasons for this recommendation: First, it appears that
+ measuring more frequently often does not in practice yield any
+ significant benefit [ALLMAN99]; second, if measurements are made
+ more often, then the values of RTO.Alpha and RTO.Beta in rule C3
+ above should be adjusted so that SRTT and RTTVAR still adjust to
+ changes at roughly the same rate (in terms of how many round
+ trips it takes them to reflect new values) as they would if
+ making only one measurement per round-trip and using RTO.Alpha
+ and RTO.Beta as given in rule C3. However, the exact nature of
+ these adjustments remains a research issue.
+
+ C5) Karn's algorithm: RTT measurements MUST NOT be made using
+ packets that were retransmitted (and thus for which it is
+ ambiguous whether the reply was for the first instance of the
+ chunk or for a later instance)
+
+ IMPLEMENTATION NOTE: RTT measurements should only be made using
+ a chunk with TSN r if no chunk with TSN less than or equal to r
+ is retransmitted since r is first sent.
+
+ C6) Whenever RTO is computed, if it is less than RTO.Min seconds
+ then it is rounded up to RTO.Min seconds. The reason for this
+ rule is that RTOs that do not have a high minimum value are
+ susceptible to unnecessary timeouts [ALLMAN99].
+
+ C7) A maximum value may be placed on RTO provided it is at least
+ RTO.max seconds.
+
+ There is no requirement for the clock granularity G used for
+ computing RTT measurements and the different state variables, other
+ than:
+
+ G1) Whenever RTTVAR is computed, if RTTVAR = 0, then adjust RTTVAR <-
+ G.
+
+ Experience [ALLMAN99] has shown that finer clock granularities (<=
+ 100 msec) perform somewhat better than more coarse granularities.
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 84]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+6.3.2. Retransmission Timer Rules
+
+ The rules for managing the retransmission timer are as follows:
+
+ R1) Every time a DATA chunk is sent to any address (including a
+ retransmission), if the T3-rtx timer of that address is not
+ running, start it running so that it will expire after the RTO
+ of that address. The RTO used here is that obtained after any
+ doubling due to previous T3-rtx timer expirations on the
+ corresponding destination address as discussed in rule E2 below.
+
+ R2) Whenever all outstanding data sent to an address have been
+ acknowledged, turn off the T3-rtx timer of that address.
+
+ R3) Whenever a SACK is received that acknowledges the DATA chunk
+ with the earliest outstanding TSN for that address, restart the
+ T3-rtx timer for that address with its current RTO (if there is
+ still outstanding data on that address).
+
+ R4) Whenever a SACK is received missing a TSN that was previously
+ acknowledged via a Gap Ack Block, start the T3-rtx for the
+ destination address to which the DATA chunk was originally
+ transmitted if it is not already running.
+
+ The following example shows the use of various timer rules (assuming
+ that the receiver uses delayed acks).
+
+ Endpoint A Endpoint Z
+ {App begins to send}
+ Data [TSN=7,Strm=0,Seq=3] ------------> (ack delayed)
+ (Start T3-rtx timer)
+ {App sends 1 message; strm 1}
+ (bundle ack with data)
+ DATA [TSN=8,Strm=0,Seq=4] ----\ /-- SACK [TSN Ack=7,Block=0]
+ \ / DATA [TSN=6,Strm=1,Seq=2]
+ \ / (Start T3-rtx timer)
+ \
+ / \
+ (Restart T3-rtx timer) <------/ \--> (ack delayed)
+ (ack delayed)
+ {send ack}
+ SACK [TSN Ack=6,Block=0] --------------> (Cancel T3-rtx timer)
+ ..
+ (send ack)
+ (Cancel T3-rtx timer) <-------------- SACK [TSN Ack=8,Block=0]
+
+ Figure 8: Timer Rule Examples
+
+
+
+
+Stewart Standards Track [Page 85]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+6.3.3. Handle T3-rtx Expiration
+
+ Whenever the retransmission timer T3-rtx expires for a destination
+ address, do the following:
+
+ E1) For the destination address for which the timer expires, adjust
+ its ssthresh with rules defined in Section 7.2.3 and set the
+ cwnd <- MTU.
+
+ E2) For the destination address for which the timer expires, set RTO
+ <- RTO * 2 ("back off the timer"). The maximum value discussed
+ in rule C7 above (RTO.max) may be used to provide an upper bound
+ to this doubling operation.
+
+ E3) Determine how many of the earliest (i.e., lowest TSN)
+ outstanding DATA chunks for the address for which the T3-rtx has
+ expired will fit into a single packet, subject to the MTU
+ constraint for the path corresponding to the destination
+ transport address to which the retransmission is being sent
+ (this may be different from the address for which the timer
+ expires; see Section 6.4). Call this value K. Bundle and
+ retransmit those K DATA chunks in a single packet to the
+ destination endpoint.
+
+ E4) Start the retransmission timer T3-rtx on the destination address
+ to which the retransmission is sent, if rule R1 above indicates
+ to do so. The RTO to be used for starting T3-rtx should be the
+ one for the destination address to which the retransmission is
+ sent, which, when the receiver is multi-homed, may be different
+ from the destination address for which the timer expired (see
+ Section 6.4 below).
+
+ After retransmitting, once a new RTT measurement is obtained (which
+ can happen only when new data has been sent and acknowledged, per
+ rule C5, or for a measurement made from a HEARTBEAT; see Section
+ 8.3), the computation in rule C3 is performed, including the
+ computation of RTO, which may result in "collapsing" RTO back down
+ after it has been subject to doubling (rule E2).
+
+ Note: Any DATA chunks that were sent to the address for which the
+ T3-rtx timer expired but did not fit in one MTU (rule E3 above)
+ should be marked for retransmission and sent as soon as cwnd allows
+ (normally, when a SACK arrives).
+
+ The final rule for managing the retransmission timer concerns
+ failover (see Section 6.4.1):
+
+
+
+
+
+Stewart Standards Track [Page 86]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ F1) Whenever an endpoint switches from the current destination
+ transport address to a different one, the current retransmission
+ timers are left running. As soon as the endpoint transmits a
+ packet containing DATA chunk(s) to the new transport address,
+ start the timer on that transport address, using the RTO value
+ of the destination address to which the data is being sent, if
+ rule R1 indicates to do so.
+
+6.4. Multi-Homed SCTP Endpoints
+
+ An SCTP endpoint is considered multi-homed if there are more than one
+ transport address that can be used as a destination address to reach
+ that endpoint.
+
+ Moreover, the ULP of an endpoint shall select one of the multiple
+ destination addresses of a multi-homed peer endpoint as the primary
+ path (see Section 5.1.2 and Section 10.1 for details).
+
+ By default, an endpoint SHOULD always transmit to the primary path,
+ unless the SCTP user explicitly specifies the destination transport
+ address (and possibly source transport address) to use.
+
+ An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,
+ etc.) to the same destination transport address from which it
+ received the DATA or control chunk to which it is replying. This
+ rule should also be followed if the endpoint is bundling DATA chunks
+ together with the reply chunk.
+
+ However, when acknowledging multiple DATA chunks received in packets
+ from different source addresses in a single SACK, the SACK chunk may
+ be transmitted to one of the destination transport addresses from
+ which the DATA or control chunks being acknowledged were received.
+
+ When a receiver of a duplicate DATA chunk sends a SACK to a multi-
+ homed endpoint, it MAY be beneficial to vary the destination address
+ and not use the source address of the DATA chunk. The reason is that
+ receiving a duplicate from a multi-homed endpoint might indicate that
+ the return path (as specified in the source address of the DATA
+ chunk) for the SACK is broken.
+
+ Furthermore, when its peer is multi-homed, an endpoint SHOULD try to
+ retransmit a chunk that timed out to an active destination transport
+ address that is different from the last destination address to which
+ the DATA chunk was sent.
+
+ Retransmissions do not affect the total outstanding data count.
+ However, if the DATA chunk is retransmitted onto a different
+ destination address, both the outstanding data counts on the new
+
+
+
+Stewart Standards Track [Page 87]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ destination address and the old destination address to which the data
+ chunk was last sent shall be adjusted accordingly.
+
+6.4.1. Failover from an Inactive Destination Address
+
+ Some of the transport addresses of a multi-homed SCTP endpoint may
+ become inactive due to either the occurrence of certain error
+ conditions (see Section 8.2) or adjustments from the SCTP user.
+
+ When there is outbound data to send and the primary path becomes
+ inactive (e.g., due to failures), or where the SCTP user explicitly
+ requests to send data to an inactive destination transport address,
+ before reporting an error to its ULP, the SCTP endpoint should try to
+ send the data to an alternate active destination transport address if
+ one exists.
+
+ When retransmitting data that timed out, if the endpoint is multi-
+ homed, it should consider each source-destination address pair in its
+ retransmission selection policy. When retransmitting timed-out data,
+ the endpoint should attempt to pick the most divergent source-
+ destination pair from the original source-destination pair to which
+ the packet was transmitted.
+
+ Note: Rules for picking the most divergent source-destination pair
+ are an implementation decision and are not specified within this
+ document.
+
+6.5. Stream Identifier and Stream Sequence Number
+
+ Every DATA chunk MUST carry a valid stream identifier. If an
+ endpoint receives a DATA chunk with an invalid stream identifier, it
+ shall acknowledge the reception of the DATA chunk following the
+ normal procedure, immediately send an ERROR chunk with cause set to
+ "Invalid Stream Identifier" (see Section 3.3.10), and discard the
+ DATA chunk. The endpoint may bundle the ERROR chunk in the same
+ packet as the SACK as long as the ERROR follows the SACK.
+
+ The Stream Sequence Number in all the streams MUST start from 0 when
+ the association is established. Also, when the Stream Sequence
+ Number reaches the value 65535 the next Stream Sequence Number MUST
+ be set to 0.
+
+6.6. Ordered and Unordered Delivery
+
+ Within a stream, an endpoint MUST deliver DATA chunks received with
+ the U flag set to 0 to the upper layer according to the order of
+ their Stream Sequence Number. If DATA chunks arrive out of order of
+
+
+
+
+Stewart Standards Track [Page 88]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ their Stream Sequence Number, the endpoint MUST hold the received
+ DATA chunks from delivery to the ULP until they are reordered.
+
+ However, an SCTP endpoint can indicate that no ordered delivery is
+ required for a particular DATA chunk transmitted within the stream by
+ setting the U flag of the DATA chunk to 1.
+
+ When an endpoint receives a DATA chunk with the U flag set to 1, it
+ must bypass the ordering mechanism and immediately deliver the data
+ to the upper layer (after reassembly if the user data is fragmented
+ by the data sender).
+
+ This provides an effective way of transmitting "out-of-band" data in
+ a given stream. Also, a stream can be used as an "unordered" stream
+ by simply setting the U flag to 1 in all DATA chunks sent through
+ that stream.
+
+ IMPLEMENTATION NOTE: When sending an unordered DATA chunk, an
+ implementation may choose to place the DATA chunk in an outbound
+ packet that is at the head of the outbound transmission queue if
+ possible.
+
+ The 'Stream Sequence Number' field in a DATA chunk with U flag set to
+ 1 has no significance. The sender can fill it with arbitrary value,
+ but the receiver MUST ignore the field.
+
+ Note: When transmitting ordered and unordered data, an endpoint does
+ not increment its Stream Sequence Number when transmitting a DATA
+ chunk with U flag set to 1.
+
+6.7. Report Gaps in Received DATA TSNs
+
+ Upon the reception of a new DATA chunk, an endpoint shall examine the
+ continuity of the TSNs received. If the endpoint detects a gap in
+ the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack
+ Blocks immediately. The data receiver continues sending a SACK after
+ receipt of each SCTP packet that doesn't fill the gap.
+
+ Based on the Gap Ack Block from the received SACK, the endpoint can
+ calculate the missing DATA chunks and make decisions on whether to
+ retransmit them (see Section 6.2.1 for details).
+
+ Multiple gaps can be reported in one single SACK (see Section 3.3.4).
+
+ When its peer is multi-homed, the SCTP endpoint SHOULD always try to
+ send the SACK to the same destination address from which the last
+ DATA chunk was received.
+
+
+
+
+Stewart Standards Track [Page 89]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Upon the reception of a SACK, the endpoint MUST remove all DATA
+ chunks that have been acknowledged by the SACK's Cumulative TSN Ack
+ from its transmit queue. The endpoint MUST also treat all the DATA
+ chunks with TSNs not included in the Gap Ack Blocks reported by the
+ SACK as "missing". The number of "missing" reports for each
+ outstanding DATA chunk MUST be recorded by the data sender in order
+ to make retransmission decisions. See Section 7.2.4 for details.
+
+ The following example shows the use of SACK to report a gap.
+
+ Endpoint A Endpoint Z {App
+ sends 3 messages; strm 0} DATA [TSN=6,Strm=0,Seq=2] ----------
+ -----> (ack delayed) (Start T3-rtx timer)
+
+ DATA [TSN=7,Strm=0,Seq=3] --------> X (lost)
+
+ DATA [TSN=8,Strm=0,Seq=4] ---------------> (gap detected,
+ immediately send ack)
+ /----- SACK [TSN Ack=6,Block=1,
+ / Start=2,End=2]
+ <-----/ (remove 6 from out-queue,
+ and mark 7 as "1" missing report)
+
+ Figure 9: Reporting a Gap using SACK
+
+ The maximum number of Gap Ack Blocks that can be reported within a
+ single SACK chunk is limited by the current path MTU. When a single
+ SACK cannot cover all the Gap Ack Blocks needed to be reported due to
+ the MTU limitation, the endpoint MUST send only one SACK, reporting
+ the Gap Ack Blocks from the lowest to highest TSNs, within the size
+ limit set by the MTU, and leave the remaining highest TSN numbers
+ unacknowledged.
+
+6.8. CRC32c Checksum Calculation
+
+ When sending an SCTP packet, the endpoint MUST strengthen the data
+ integrity of the transmission by including the CRC32c checksum value
+ calculated on the packet, as described below.
+
+ After the packet is constructed (containing the SCTP common header
+ and one or more control or DATA chunks), the transmitter MUST
+
+ 1) fill in the proper Verification Tag in the SCTP common header and
+ initialize the checksum field to '0's,
+
+ 2) calculate the CRC32c checksum of the whole packet, including the
+ SCTP common header and all the chunks (refer to Appendix B for
+ details of the CRC32c algorithm); and
+
+
+
+Stewart Standards Track [Page 90]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 3) put the resultant value into the checksum field in the common
+ header, and leave the rest of the bits unchanged.
+
+ When an SCTP packet is received, the receiver MUST first check the
+ CRC32c checksum as follows:
+
+ 1) Store the received CRC32c checksum value aside.
+
+ 2) Replace the 32 bits of the checksum field in the received SCTP
+ packet with all '0's and calculate a CRC32c checksum value of the
+ whole received packet.
+
+ 3) Verify that the calculated CRC32c checksum is the same as the
+ received CRC32c checksum. If it is not, the receiver MUST treat
+ the packet as an invalid SCTP packet.
+
+ The default procedure for handling invalid SCTP packets is to
+ silently discard them.
+
+ Any hardware implementation SHOULD be done in a way that is
+ verifiable by the software.
+
+6.9. Fragmentation and Reassembly
+
+ An endpoint MAY support fragmentation when sending DATA chunks, but
+ it MUST support reassembly when receiving DATA chunks. If an
+ endpoint supports fragmentation, it MUST fragment a user message if
+ the size of the user message to be sent causes the outbound SCTP
+ packet size to exceed the current MTU. If an implementation does not
+ support fragmentation of outbound user messages, the endpoint MUST
+ return an error to its upper layer and not attempt to send the user
+ message.
+
+ Note: If an implementation that supports fragmentation makes
+ available to its upper layer a mechanism to turn off fragmentation,
+ it may do so. However, in so doing, it MUST react just like an
+ implementation that does NOT support fragmentation, i.e., it MUST
+ reject sends that exceed the current Path MTU (P-MTU).
+
+ IMPLEMENTATION NOTE: In this error case, the Send primitive discussed
+ in Section 10.1 would need to return an error to the upper layer.
+
+ If its peer is multi-homed, the endpoint shall choose a size no
+ larger than the association Path MTU. The association Path MTU is
+ the smallest Path MTU of all destination addresses.
+
+
+
+
+
+
+Stewart Standards Track [Page 91]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Note: Once a message is fragmented, it cannot be re-fragmented.
+ Instead, if the PMTU has been reduced, then IP fragmentation must be
+ used. Please see Section 7.3 for details of PMTU discovery.
+
+ When determining when to fragment, the SCTP implementation MUST take
+ into account the SCTP packet header as well as the DATA chunk
+ header(s). The implementation MUST also take into account the space
+ required for a SACK chunk if bundling a SACK chunk with the DATA
+ chunk.
+
+ Fragmentation takes the following steps:
+
+ 1) The data sender MUST break the user message into a series of DATA
+ chunks such that each chunk plus SCTP overhead fits into an IP
+ datagram smaller than or equal to the association Path MTU.
+
+ 2) The transmitter MUST then assign, in sequence, a separate TSN to
+ each of the DATA chunks in the series. The transmitter assigns
+ the same SSN to each of the DATA chunks. If the user indicates
+ that the user message is to be delivered using unordered
+ delivery, then the U flag of each DATA chunk of the user message
+ MUST be set to 1.
+
+ 3) The transmitter MUST also set the B/E bits of the first DATA
+ chunk in the series to '10', the B/E bits of the last DATA chunk
+ in the series to '01', and the B/E bits of all other DATA chunks
+ in the series to '00'.
+
+ An endpoint MUST recognize fragmented DATA chunks by examining the
+ B/E bits in each of the received DATA chunks, and queue the
+ fragmented DATA chunks for reassembly. Once the user message is
+ reassembled, SCTP shall pass the reassembled user message to the
+ specific stream for possible reordering and final dispatching.
+
+ Note: If the data receiver runs out of buffer space while still
+ waiting for more fragments to complete the reassembly of the message,
+ it should dispatch part of its inbound message through a partial
+ delivery API (see Section 10), freeing some of its receive buffer
+ space so that the rest of the message may be received.
+
+6.10. Bundling
+
+ An endpoint bundles chunks by simply including multiple chunks in one
+ outbound SCTP packet. The total size of the resultant IP datagram,
+
+ including the SCTP packet and IP headers, MUST be less that or equal
+ to the current Path MTU.
+
+
+
+
+Stewart Standards Track [Page 92]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ If its peer endpoint is multi-homed, the sending endpoint shall
+ choose a size no larger than the latest MTU of the current primary
+ path.
+
+ When bundling control chunks with DATA chunks, an endpoint MUST place
+ control chunks first in the outbound SCTP packet. The transmitter
+ MUST transmit DATA chunks within an SCTP packet in increasing order
+ of TSN.
+
+ Note: Since control chunks must be placed first in a packet and since
+ DATA chunks must be transmitted before SHUTDOWN or SHUTDOWN ACK
+ chunks, DATA chunks cannot be bundled with SHUTDOWN or SHUTDOWN ACK
+ chunks.
+
+ Partial chunks MUST NOT be placed in an SCTP packet. A partial chunk
+ is a chunk that is not completely contained in the SCTP packet; i.e.,
+ the SCTP packet is too short to contain all the bytes of the chunk as
+ indicated by the chunk length.
+
+ An endpoint MUST process received chunks in their order in the
+ packet. The receiver uses the Chunk Length field to determine the
+ end of a chunk and beginning of the next chunk taking account of the
+ fact that all chunks end on a 4-byte boundary. If the receiver
+ detects a partial chunk, it MUST drop the chunk.
+
+ An endpoint MUST NOT bundle INIT, INIT ACK, or SHUTDOWN COMPLETE with
+ any other chunks.
+
+7. Congestion Control
+
+ Congestion control is one of the basic functions in SCTP. For some
+ applications, it may be likely that adequate resources will be
+ allocated to SCTP traffic to ensure prompt delivery of time-critical
+ data -- thus, it would appear to be unlikely, during normal
+ operations, that transmissions encounter severe congestion
+ conditions. However, SCTP must operate under adverse operational
+ conditions, which can develop upon partial network failures or
+ unexpected traffic surges. In such situations, SCTP must follow
+ correct congestion control steps to recover from congestion quickly
+ in order to get data delivered as soon as possible. In the absence
+ of network congestion, these preventive congestion control algorithms
+ should show no impact on the protocol performance.
+
+ IMPLEMENTATION NOTE: As far as its specific performance requirements
+ are met, an implementation is always allowed to adopt a more
+ conservative congestion control algorithm than the one defined below.
+
+
+
+
+
+Stewart Standards Track [Page 93]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The congestion control algorithms used by SCTP are based on
+ [RFC2581]. This section describes how the algorithms defined in
+ [RFC2581] are adapted for use in SCTP. We first list differences in
+ protocol designs between TCP and SCTP, and then describe SCTP's
+ congestion control scheme. The description will use the same
+ terminology as in TCP congestion control whenever appropriate.
+
+ SCTP congestion control is always applied to the entire association,
+ and not to individual streams.
+
+7.1. SCTP Differences from TCP Congestion Control
+
+ Gap Ack Blocks in the SCTP SACK carry the same semantic meaning as
+ the TCP SACK. TCP considers the information carried in the SACK as
+ advisory information only. SCTP considers the information carried in
+ the Gap Ack Blocks in the SACK chunk as advisory. In SCTP, any DATA
+ chunk that has been acknowledged by SACK, including DATA that arrived
+ at the receiving end out of order, is not considered fully delivered
+ until the Cumulative TSN Ack Point passes the TSN of the DATA chunk
+ (i.e., the DATA chunk has been acknowledged by the Cumulative TSN Ack
+ field in the SACK). Consequently, the value of cwnd controls the
+ amount of outstanding data, rather than (as in the case of non-SACK
+ TCP) the upper bound between the highest acknowledged sequence number
+ and the latest DATA chunk that can be sent within the congestion
+ window. SCTP SACK leads to different implementations of Fast
+ Retransmit and Fast Recovery than non-SACK TCP. As an example, see
+ [FALL96].
+
+ The biggest difference between SCTP and TCP, however, is multi-
+ homing. SCTP is designed to establish robust communication
+ associations between two endpoints each of which may be reachable by
+ more than one transport address. Potentially different addresses may
+ lead to different data paths between the two endpoints; thus, ideally
+ one may need a separate set of congestion control parameters for each
+ of the paths. The treatment here of congestion control for multi-
+ homed receivers is new with SCTP and may require refinement in the
+ future. The current algorithms make the following assumptions:
+
+ o The sender usually uses the same destination address until being
+ instructed by the upper layer to do otherwise; however, SCTP may
+ change to an alternate destination in the event an address is
+ marked inactive (see Section 8.2). Also, SCTP may retransmit to a
+ different transport address than the original transmission.
+
+ o The sender keeps a separate congestion control parameter set for
+ each of the destination addresses it can send to (not each
+ source-destination pair but for each destination). The parameters
+
+
+
+
+Stewart Standards Track [Page 94]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ should decay if the address is not used for a long enough time
+ period.
+
+ o For each of the destination addresses, an endpoint does slow start
+ upon the first transmission to that address.
+
+ Note: TCP guarantees in-sequence delivery of data to its upper-layer
+ protocol within a single TCP session. This means that when TCP
+ notices a gap in the received sequence number, it waits until the gap
+ is filled before delivering the data that was received with sequence
+ numbers higher than that of the missing data. On the other hand,
+ SCTP can deliver data to its upper-layer protocol even if there is a
+ gap in TSN if the Stream Sequence Numbers are in sequence for a
+ particular stream (i.e., the missing DATA chunks are for a different
+ stream) or if unordered delivery is indicated. Although this does
+ not affect cwnd, it might affect rwnd calculation.
+
+7.2. SCTP Slow-Start and Congestion Avoidance
+
+ The slow-start and congestion avoidance algorithms MUST be used by an
+ endpoint to control the amount of data being injected into the
+ network. The congestion control in SCTP is employed in regard to the
+ association, not to an individual stream. In some situations, it may
+ be beneficial for an SCTP sender to be more conservative than the
+ algorithms allow; however, an SCTP sender MUST NOT be more aggressive
+ than the following algorithms allow.
+
+ Like TCP, an SCTP endpoint uses the following three control variables
+ to regulate its transmission rate.
+
+ o Receiver advertised window size (rwnd, in bytes), which is set by
+ the receiver based on its available buffer space for incoming
+ packets.
+
+ Note: This variable is kept on the entire association.
+
+ o Congestion control window (cwnd, in bytes), which is adjusted by
+ the sender based on observed network conditions.
+
+ Note: This variable is maintained on a per-destination-address
+ basis.
+
+ o Slow-start threshold (ssthresh, in bytes), which is used by the
+ sender to distinguish slow-start and congestion avoidance phases.
+
+ Note: This variable is maintained on a per-destination-address
+ basis.
+
+
+
+
+Stewart Standards Track [Page 95]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ SCTP also requires one additional control variable,
+ partial_bytes_acked, which is used during congestion avoidance phase
+ to facilitate cwnd adjustment.
+
+ Unlike TCP, an SCTP sender MUST keep a set of these control variables
+ cwnd, ssthresh, and partial_bytes_acked for EACH destination address
+ of its peer (when its peer is multi-homed). Only one rwnd is kept
+ for the whole association (no matter if the peer is multi-homed or
+ has a single address).
+
+7.2.1. Slow-Start
+
+ Beginning data transmission into a network with unknown conditions or
+ after a sufficiently long idle period requires SCTP to probe the
+ network to determine the available capacity. The slow-start
+ algorithm is used for this purpose at the beginning of a transfer, or
+ after repairing loss detected by the retransmission timer.
+
+ o The initial cwnd before DATA transmission or after a sufficiently
+ long idle period MUST be set to min(4*MTU, max (2*MTU, 4380
+ bytes)).
+
+ o The initial cwnd after a retransmission timeout MUST be no more
+ than 1*MTU.
+
+ o The initial value of ssthresh MAY be arbitrarily high (for
+ example, implementations MAY use the size of the receiver
+ advertised window).
+
+ o Whenever cwnd is greater than zero, the endpoint is allowed to
+ have cwnd bytes of data outstanding on that transport address.
+
+ o When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
+ use the slow-start algorithm to increase cwnd only if the current
+ congestion window is being fully utilized, an incoming SACK
+ advances the Cumulative TSN Ack Point, and the data sender is not
+ in Fast Recovery. Only when these three conditions are met can
+ the cwnd be increased; otherwise, the cwnd MUST not be increased.
+ If these conditions are met, then cwnd MUST be increased by, at
+ most, the lesser of 1) the total size of the previously
+ outstanding DATA chunk(s) acknowledged, and 2) the destination's
+ path MTU. This upper bound protects against the ACK-Splitting
+ attack outlined in [SAVAGE99].
+
+ In instances where its peer endpoint is multi-homed, if an endpoint
+ receives a SACK that advances its Cumulative TSN Ack Point, then it
+ should update its cwnd (or cwnds) apportioned to the destination
+ addresses to which it transmitted the acknowledged data. However, if
+
+
+
+Stewart Standards Track [Page 96]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ the received SACK does not advance the Cumulative TSN Ack Point, the
+ endpoint MUST NOT adjust the cwnd of any of the destination
+ addresses.
+
+ Because an endpoint's cwnd is not tied to its Cumulative TSN Ack
+ Point, as duplicate SACKs come in, even though they may not advance
+ the Cumulative TSN Ack Point an endpoint can still use them to clock
+ out new data. That is, the data newly acknowledged by the SACK
+ diminishes the amount of data now in flight to less than cwnd, and so
+ the current, unchanged value of cwnd now allows new data to be sent.
+ On the other hand, the increase of cwnd must be tied to the
+ Cumulative TSN Ack Point advancement as specified above. Otherwise,
+ the duplicate SACKs will not only clock out new data, but also will
+ adversely clock out more new data than what has just left the
+ network, during a time of possible congestion.
+
+ o When the endpoint does not transmit data on a given transport
+ address, the cwnd of the transport address should be adjusted to
+ max(cwnd/2, 4*MTU) per RTO.
+
+7.2.2. Congestion Avoidance
+
+ When cwnd is greater than ssthresh, cwnd should be incremented by
+ 1*MTU per RTT if the sender has cwnd or more bytes of data
+ outstanding for the corresponding transport address.
+
+ In practice, an implementation can achieve this goal in the following
+ way:
+
+ o partial_bytes_acked is initialized to 0.
+
+ o Whenever cwnd is greater than ssthresh, upon each SACK arrival
+ that advances the Cumulative TSN Ack Point, increase
+ partial_bytes_acked by the total number of bytes of all new chunks
+ acknowledged in that SACK including chunks acknowledged by the new
+ Cumulative TSN Ack and by Gap Ack Blocks.
+
+ o When partial_bytes_acked is equal to or greater than cwnd and
+ before the arrival of the SACK the sender had cwnd or more bytes
+ of data outstanding (i.e., before arrival of the SACK, flightsize
+ was greater than or equal to cwnd), increase cwnd by MTU, and
+ reset partial_bytes_acked to (partial_bytes_acked - cwnd).
+
+ o Same as in the slow start, when the sender does not transmit DATA
+ on a given transport address, the cwnd of the transport address
+ should be adjusted to max(cwnd / 2, 4*MTU) per RTO.
+
+
+
+
+
+Stewart Standards Track [Page 97]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o When all of the data transmitted by the sender has been
+ acknowledged by the receiver, partial_bytes_acked is initialized
+ to 0.
+
+7.2.3. Congestion Control
+
+ Upon detection of packet losses from SACK (see Section 7.2.4), an
+ endpoint should do the following:
+
+ ssthresh = max(cwnd/2, 4*MTU)
+ cwnd = ssthresh
+ partial_bytes_acked = 0
+
+ Basically, a packet loss causes cwnd to be cut in half.
+
+ When the T3-rtx timer expires on an address, SCTP should perform slow
+ start by:
+
+ ssthresh = max(cwnd/2, 4*MTU)
+ cwnd = 1*MTU
+
+ and ensure that no more than one SCTP packet will be in flight for
+ that address until the endpoint receives acknowledgement for
+ successful delivery of data to that address.
+
+7.2.4. Fast Retransmit on Gap Reports
+
+ In the absence of data loss, an endpoint performs delayed
+ acknowledgement. However, whenever an endpoint notices a hole in the
+ arriving TSN sequence, it SHOULD start sending a SACK back every time
+ a packet arrives carrying data until the hole is filled.
+
+ Whenever an endpoint receives a SACK that indicates that some TSNs
+ are missing, it SHOULD wait for two further miss indications (via
+ subsequent SACKs for a total of three missing reports) on the same
+ TSNs before taking action with regard to Fast Retransmit.
+
+ Miss indications SHOULD follow the HTNA (Highest TSN Newly
+ Acknowledged) algorithm. For each incoming SACK, miss indications
+ are incremented only for missing TSNs prior to the highest TSN newly
+ acknowledged in the SACK. A newly acknowledged DATA chunk is one not
+ previously acknowledged in a SACK. If an endpoint is in Fast
+ Recovery and a SACK arrives that advances the Cumulative TSN Ack
+ Point, the miss indications are incremented for all TSNs reported
+ missing in the SACK.
+
+ When the third consecutive miss indication is received for a TSN(s),
+ the data sender shall do the following:
+
+
+
+Stewart Standards Track [Page 98]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 1) Mark the DATA chunk(s) with three miss indications for
+ retransmission.
+
+ 2) If not in Fast Recovery, adjust the ssthresh and cwnd of the
+ destination address(es) to which the missing DATA chunks were
+ last sent, according to the formula described in Section 7.2.3.
+
+ 3) Determine how many of the earliest (i.e., lowest TSN) DATA chunks
+ marked for retransmission will fit into a single packet, subject
+ to constraint of the path MTU of the destination transport
+ address to which the packet is being sent. Call this value K.
+ Retransmit those K DATA chunks in a single packet. When a Fast
+ Retransmit is being performed, the sender SHOULD ignore the value
+ of cwnd and SHOULD NOT delay retransmission for this single
+ packet.
+
+ 4) Restart the T3-rtx timer only if the last SACK acknowledged the
+ lowest outstanding TSN number sent to that address, or the
+ endpoint is retransmitting the first outstanding DATA chunk sent
+ to that address.
+
+ 5) Mark the DATA chunk(s) as being fast retransmitted and thus
+ ineligible for a subsequent Fast Retransmit. Those TSNs marked
+ for retransmission due to the Fast-Retransmit algorithm that did
+ not fit in the sent datagram carrying K other TSNs are also
+ marked as ineligible for a subsequent Fast Retransmit. However,
+ as they are marked for retransmission they will be retransmitted
+ later on as soon as cwnd allows.
+
+ 6) If not in Fast Recovery, enter Fast Recovery and mark the highest
+ outstanding TSN as the Fast Recovery exit point. When a SACK
+ acknowledges all TSNs up to and including this exit point, Fast
+ Recovery is exited. While in Fast Recovery, the ssthresh and
+ cwnd SHOULD NOT change for any destinations due to a subsequent
+ Fast Recovery event (i.e., one SHOULD NOT reduce the cwnd further
+ due to a subsequent Fast Retransmit).
+
+ Note: Before the above adjustments, if the received SACK also
+ acknowledges new DATA chunks and advances the Cumulative TSN Ack
+ Point, the cwnd adjustment rules defined in Section 7.2.1 and Section
+ 7.2.2 must be applied first.
+
+ A straightforward implementation of the above keeps a counter for
+ each TSN hole reported by a SACK. The counter increments for each
+ consecutive SACK reporting the TSN hole. After reaching 3 and
+ starting the Fast-Retransmit procedure, the counter resets to 0.
+
+
+
+
+
+Stewart Standards Track [Page 99]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Because cwnd in SCTP indirectly bounds the number of outstanding
+ TSN's, the effect of TCP Fast Recovery is achieved automatically with
+ no adjustment to the congestion control window size.
+
+7.3. Path MTU Discovery
+
+ [RFC4821], [RFC1981], and [RFC1191] specify "Packetization Layer Path
+ MTU Discovery", whereby an endpoint maintains an estimate of the
+ maximum transmission unit (MTU) along a given Internet path and
+ refrains from sending packets along that path that exceed the MTU,
+ other than occasional attempts to probe for a change in the Path MTU
+ (PMTU). [RFC4821] is thorough in its discussion of the MTU discovery
+ mechanism and strategies for determining the current end-to-end MTU
+ setting as well as detecting changes in this value.
+
+ An endpoint SHOULD apply these techniques, and SHOULD do so on a
+ per-destination-address basis.
+
+ There are two important SCTP-specific points regarding Path MTU
+ discovery:
+
+ 1) SCTP associations can span multiple addresses. An endpoint MUST
+ maintain separate MTU estimates for each destination address of
+ its peer.
+
+ 2) The sender should track an association PMTU that will be the
+ smallest PMTU discovered for all of the peer's destination
+ addresses. When fragmenting messages into multiple parts this
+ association PMTU should be used to calculate the size of each
+ fragment. This will allow retransmissions to be seamlessly sent
+ to an alternate address without encountering IP fragmentation.
+
+8. Fault Management
+
+8.1. Endpoint Failure Detection
+
+ An endpoint shall keep a counter on the total number of consecutive
+ retransmissions to its peer (this includes retransmissions to all the
+ destination transport addresses of the peer if it is multi-homed),
+ including unacknowledged HEARTBEAT chunks. If the value of this
+ counter exceeds the limit indicated in the protocol parameter
+ 'Association.Max.Retrans', the endpoint shall consider the peer
+ endpoint unreachable and shall stop transmitting any more data to it
+ (and thus the association enters the CLOSED state). In addition, the
+ endpoint MAY report the failure to the upper layer and optionally
+ report back all outstanding user data remaining in its outbound
+ queue. The association is automatically closed when the peer
+ endpoint becomes unreachable.
+
+
+
+Stewart Standards Track [Page 100]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The counter shall be reset each time a DATA chunk sent to that peer
+ endpoint is acknowledged (by the reception of a SACK) or a HEARTBEAT
+ ACK is received from the peer endpoint.
+
+8.2. Path Failure Detection
+
+ When its peer endpoint is multi-homed, an endpoint should keep an
+ error counter for each of the destination transport addresses of the
+ peer endpoint.
+
+ Each time the T3-rtx timer expires on any address, or when a
+ HEARTBEAT sent to an idle address is not acknowledged within an RTO,
+ the error counter of that destination address will be incremented.
+ When the value in the error counter exceeds the protocol parameter
+ 'Path.Max.Retrans' of that destination address, the endpoint should
+ mark the destination transport address as inactive, and a
+ notification SHOULD be sent to the upper layer.
+
+ When an outstanding TSN is acknowledged or a HEARTBEAT sent to that
+ address is acknowledged with a HEARTBEAT ACK, the endpoint shall
+ clear the error counter of the destination transport address to which
+ the DATA chunk was last sent (or HEARTBEAT was sent). When the peer
+ endpoint is multi-homed and the last chunk sent to it was a
+ retransmission to an alternate address, there exists an ambiguity as
+ to whether or not the acknowledgement should be credited to the
+ address of the last chunk sent. However, this ambiguity does not
+ seem to bear any significant consequence to SCTP behavior. If this
+ ambiguity is undesirable, the transmitter may choose not to clear the
+ error counter if the last chunk sent was a retransmission.
+
+ Note: When configuring the SCTP endpoint, the user should avoid
+ having the value of 'Association.Max.Retrans' larger than the
+ summation of the 'Path.Max.Retrans' of all the destination addresses
+ for the remote endpoint. Otherwise, all the destination addresses
+ may become inactive while the endpoint still considers the peer
+ endpoint reachable. When this condition occurs, how SCTP chooses to
+ function is implementation specific.
+
+ When the primary path is marked inactive (due to excessive
+ retransmissions, for instance), the sender MAY automatically transmit
+ new packets to an alternate destination address if one exists and is
+ active. If more than one alternate address is active when the
+ primary path is marked inactive, only ONE transport address SHOULD be
+ chosen and used as the new destination transport address.
+
+
+
+
+
+
+
+Stewart Standards Track [Page 101]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+8.3. Path Heartbeat
+
+ By default, an SCTP endpoint SHOULD monitor the reachability of the
+ idle destination transport address(es) of its peer by sending a
+ HEARTBEAT chunk periodically to the destination transport
+ address(es). HEARTBEAT sending MAY begin upon reaching the
+ ESTABLISHED state and is discontinued after sending either SHUTDOWN
+ or SHUTDOWN-ACK. A receiver of a HEARTBEAT MUST respond to a
+ HEARTBEAT with a HEARTBEAT-ACK after entering the COOKIE-ECHOED state
+ (INIT sender) or the ESTABLISHED state (INIT receiver), up until
+ reaching the SHUTDOWN-SENT state (SHUTDOWN sender) or the SHUTDOWN-
+ ACK-SENT state (SHUTDOWN receiver).
+
+ A destination transport address is considered "idle" if no new chunk
+ that can be used for updating path RTT (usually including first
+ transmission DATA, INIT, COOKIE ECHO, HEARTBEAT, etc.) and no
+ HEARTBEAT has been sent to it within the current heartbeat period of
+ that address. This applies to both active and inactive destination
+ addresses.
+
+ The upper layer can optionally initiate the following functions:
+
+ A) Disable heartbeat on a specific destination transport address of a
+ given association,
+
+ B) Change the HB.interval,
+
+ C) Re-enable heartbeat on a specific destination transport address of
+ a given association, and
+
+ D) Request an on-demand HEARTBEAT on a specific destination transport
+ address of a given association.
+
+ The endpoint should increment the respective error counter of the
+ destination transport address each time a HEARTBEAT is sent to that
+ address and not acknowledged within one RTO.
+
+ When the value of this counter reaches the protocol parameter
+ 'Path.Max.Retrans', the endpoint should mark the corresponding
+ destination address as inactive if it is not so marked, and may also
+ optionally report to the upper layer the change of reachability of
+ this destination address. After this, the endpoint should continue
+ HEARTBEAT on this destination address but should stop increasing the
+ counter.
+
+ The sender of the HEARTBEAT chunk should include in the Heartbeat
+ Information field of the chunk the current time when the packet is
+ sent out and the destination address to which the packet is sent.
+
+
+
+Stewart Standards Track [Page 102]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ IMPLEMENTATION NOTE: An alternative implementation of the heartbeat
+ mechanism that can be used is to increment the error counter variable
+ every time a HEARTBEAT is sent to a destination. Whenever a
+ HEARTBEAT ACK arrives, the sender SHOULD clear the error counter of
+ the destination that the HEARTBEAT was sent to. This in effect would
+ clear the previously stroked error (and any other error counts as
+ well).
+
+ The receiver of the HEARTBEAT should immediately respond with a
+ HEARTBEAT ACK that contains the Heartbeat Information TLV, together
+ with any other received TLVs, copied unchanged from the received
+ HEARTBEAT chunk.
+
+ Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT
+ should clear the error counter of the destination transport address
+ to which the HEARTBEAT was sent, and mark the destination transport
+ address as active if it is not so marked. The endpoint may
+ optionally report to the upper layer when an inactive destination
+ address is marked as active due to the reception of the latest
+ HEARTBEAT ACK. The receiver of the HEARTBEAT ACK must also clear the
+ association overall error count as well (as defined in Section 8.1).
+
+ The receiver of the HEARTBEAT ACK should also perform an RTT
+ measurement for that destination transport address using the time
+ value carried in the HEARTBEAT ACK chunk.
+
+ On an idle destination address that is allowed to heartbeat, it is
+ recommended that a HEARTBEAT chunk is sent once per RTO of that
+ destination address plus the protocol parameter 'HB.interval', with
+ jittering of +/- 50% of the RTO value, and exponential backoff of the
+ RTO if the previous HEARTBEAT is unanswered.
+
+ A primitive is provided for the SCTP user to change the HB.interval
+ and turn on or off the heartbeat on a given destination address. The
+ heartbeat interval set by the SCTP user is added to the RTO of that
+ destination (including any exponential backoff). Only one heartbeat
+ should be sent each time the heartbeat timer expires (if multiple
+ destinations are idle). It is an implementation decision on how to
+ choose which of the candidate idle destinations to heartbeat to (if
+ more than one destination is idle).
+
+ Note: When tuning the heartbeat interval, there is a side effect that
+ SHOULD be taken into account. When this value is increased, i.e.,
+ the HEARTBEAT takes longer, the detection of lost ABORT messages
+ takes longer as well. If a peer endpoint ABORTs the association for
+ any reason and the ABORT chunk is lost, the local endpoint will only
+ discover the lost ABORT by sending a DATA chunk or HEARTBEAT chunk
+ (thus causing the peer to send another ABORT). This must be
+
+
+
+Stewart Standards Track [Page 103]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ considered when tuning the HEARTBEAT timer. If the HEARTBEAT is
+ disabled, only sending DATA to the association will discover a lost
+ ABORT from the peer.
+
+8.4. Handle "Out of the Blue" Packets
+
+ An SCTP packet is called an "out of the blue" (OOTB) packet if it is
+ correctly formed (i.e., passed the receiver's CRC32c check; see
+ Section 6.8), but the receiver is not able to identify the
+ association to which this packet belongs.
+
+ The receiver of an OOTB packet MUST do the following:
+
+ 1) If the OOTB packet is to or from a non-unicast address, a
+ receiver SHOULD silently discard the packet. Otherwise,
+
+ 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
+ silently discard the OOTB packet and take no further action.
+ Otherwise,
+
+ 3) If the packet contains an INIT chunk with a Verification Tag set
+ to '0', process it as described in Section 5.1. If, for whatever
+ reason, the INIT cannot be processed normally and an ABORT has to
+ be sent in response, the Verification Tag of the packet
+ containing the ABORT chunk MUST be the Initiate Tag of the
+ received INIT chunk, and the T bit of the ABORT chunk has to be
+ set to 0, indicating that the Verification Tag is NOT reflected.
+
+ 4) If the packet contains a COOKIE ECHO in the first chunk, process
+ it as described in Section 5.1. Otherwise,
+
+ 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
+ respond to the sender of the OOTB packet with a SHUTDOWN
+ COMPLETE. When sending the SHUTDOWN COMPLETE, the receiver of
+ the OOTB packet must fill in the Verification Tag field of the
+ outbound packet with the Verification Tag received in the
+ SHUTDOWN ACK and set the T bit in the Chunk Flags to indicate
+ that the Verification Tag is reflected. Otherwise,
+
+ 6) If the packet contains a SHUTDOWN COMPLETE chunk, the receiver
+ should silently discard the packet and take no further action.
+ Otherwise,
+
+ 7) If the packet contains a "Stale Cookie" ERROR or a COOKIE ACK,
+ the SCTP packet should be silently discarded. Otherwise,
+
+
+
+
+
+
+Stewart Standards Track [Page 104]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 8) The receiver should respond to the sender of the OOTB packet with
+ an ABORT. When sending the ABORT, the receiver of the OOTB
+ packet MUST fill in the Verification Tag field of the outbound
+ packet with the value found in the Verification Tag field of the
+ OOTB packet and set the T bit in the Chunk Flags to indicate that
+ the Verification Tag is reflected. After sending this ABORT, the
+ receiver of the OOTB packet shall discard the OOTB packet and
+ take no further action.
+
+8.5. Verification Tag
+
+ The Verification Tag rules defined in this section apply when sending
+ or receiving SCTP packets that do not contain an INIT, SHUTDOWN
+ COMPLETE, COOKIE ECHO (see Section 5.1), ABORT, or SHUTDOWN ACK
+ chunk. The rules for sending and receiving SCTP packets containing
+ one of these chunk types are discussed separately in Section 8.5.1.
+
+ When sending an SCTP packet, the endpoint MUST fill in the
+ Verification Tag field of the outbound packet with the tag value in
+ the Initiate Tag parameter of the INIT or INIT ACK received from its
+ peer.
+
+ When receiving an SCTP packet, the endpoint MUST ensure that the
+ value in the Verification Tag field of the received SCTP packet
+ matches its own tag. If the received Verification Tag value does not
+ match the receiver's own tag value, the receiver shall silently
+ discard the packet and shall not process it any further except for
+ those cases listed in Section 8.5.1 below.
+
+8.5.1. Exceptions in Verification Tag Rules
+
+ A) Rules for packet carrying INIT:
+
+ - The sender MUST set the Verification Tag of the packet to 0.
+
+ - When an endpoint receives an SCTP packet with the Verification
+ Tag set to 0, it should verify that the packet contains only an
+ INIT chunk. Otherwise, the receiver MUST silently discard the
+ packet.
+
+ B) Rules for packet carrying ABORT:
+
+ - The endpoint MUST always fill in the Verification Tag field of
+ the outbound packet with the destination endpoint's tag value, if
+ it is known.
+
+ - If the ABORT is sent in response to an OOTB packet, the endpoint
+ MUST follow the procedure described in Section 8.4.
+
+
+
+Stewart Standards Track [Page 105]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ - The receiver of an ABORT MUST accept the packet if the
+ Verification Tag field of the packet matches its own tag and the
+ T bit is not set OR if it is set to its peer's tag and the T bit
+ is set in the Chunk Flags. Otherwise, the receiver MUST silently
+ discard the packet and take no further action.
+
+ C) Rules for packet carrying SHUTDOWN COMPLETE:
+
+ - When sending a SHUTDOWN COMPLETE, if the receiver of the SHUTDOWN
+ ACK has a TCB, then the destination endpoint's tag MUST be used,
+ and the T bit MUST NOT be set. Only where no TCB exists should
+ the sender use the Verification Tag from the SHUTDOWN ACK, and
+ MUST set the T bit.
+
+ - The receiver of a SHUTDOWN COMPLETE shall accept the packet if
+ the Verification Tag field of the packet matches its own tag and
+ the T bit is not set OR if it is set to its peer's tag and the T
+ bit is set in the Chunk Flags. Otherwise, the receiver MUST
+ silently discard the packet and take no further action. An
+ endpoint MUST ignore the SHUTDOWN COMPLETE if it is not in the
+ SHUTDOWN-ACK-SENT state.
+
+ D) Rules for packet carrying a COOKIE ECHO
+
+ - When sending a COOKIE ECHO, the endpoint MUST use the value of
+ the Initiate Tag received in the INIT ACK.
+
+ - The receiver of a COOKIE ECHO follows the procedures in Section
+ 5.
+
+ E) Rules for packet carrying a SHUTDOWN ACK
+
+ - If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the
+ procedures in Section 8.4 SHOULD be followed; in other words, it
+ should be treated as an Out Of The Blue packet.
+
+9. Termination of Association
+
+ An endpoint should terminate its association when it exits from
+ service. An association can be terminated by either abort or
+ shutdown. An abort of an association is abortive by definition in
+ that any data pending on either end of the association is discarded
+ and not delivered to the peer. A shutdown of an association is
+ considered a graceful close where all data in queue by either
+ endpoint is delivered to the respective peers. However, in the case
+ of a shutdown, SCTP does not support a half-open state (like TCP)
+ wherein one side may continue sending data while the other end is
+ closed. When either endpoint performs a shutdown, the association on
+
+
+
+Stewart Standards Track [Page 106]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ each peer will stop accepting new data from its user and only deliver
+ data in queue at the time of sending or receiving the SHUTDOWN chunk.
+
+9.1. Abort of an Association
+
+ When an endpoint decides to abort an existing association, it MUST
+ send an ABORT chunk to its peer endpoint. The sender MUST fill in
+ the peer's Verification Tag in the outbound packet and MUST NOT
+ bundle any DATA chunk with the ABORT. If the association is aborted
+ on request of the upper layer, a User-Initiated Abort error cause
+ (see Section 3.3.10.12) SHOULD be present in the ABORT chunk.
+
+ An endpoint MUST NOT respond to any received packet that contains an
+ ABORT chunk (also see Section 8.4).
+
+ An endpoint receiving an ABORT MUST apply the special Verification
+ Tag check rules described in Section 8.5.1.
+
+ After checking the Verification Tag, the receiving endpoint MUST
+ remove the association from its record and SHOULD report the
+ termination to its upper layer. If a User-Initiated Abort error
+ cause is present in the ABORT chunk, the Upper Layer Abort Reason
+ SHOULD be made available to the upper layer.
+
+9.2. Shutdown of an Association
+
+ Using the SHUTDOWN primitive (see Section 10.1), the upper layer of
+ an endpoint in an association can gracefully close the association.
+ This will allow all outstanding DATA chunks from the peer of the
+ shutdown initiator to be delivered before the association terminates.
+
+ Upon receipt of the SHUTDOWN primitive from its upper layer, the
+ endpoint enters the SHUTDOWN-PENDING state and remains there until
+ all outstanding data has been acknowledged by its peer. The endpoint
+ accepts no new data from its upper layer, but retransmits data to the
+ far end if necessary to fill gaps.
+
+ Once all its outstanding data has been acknowledged, the endpoint
+ shall send a SHUTDOWN chunk to its peer including in the Cumulative
+ TSN Ack field the last sequential TSN it has received from the peer.
+ It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT
+ state. If the timer expires, the endpoint must resend the SHUTDOWN
+ with the updated last sequential TSN received from its peer.
+
+ The rules in Section 6.3 MUST be followed to determine the proper
+ timer value for T2-shutdown. To indicate any gaps in TSN, the
+ endpoint may also bundle a SACK with the SHUTDOWN chunk in the same
+ SCTP packet.
+
+
+
+Stewart Standards Track [Page 107]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ An endpoint should limit the number of retransmissions of the
+ SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.
+ If this threshold is exceeded, the endpoint should destroy the TCB
+ and MUST report the peer endpoint unreachable to the upper layer (and
+ thus the association enters the CLOSED state). The reception of any
+ packet from its peer (i.e., as the peer sends all of its queued DATA
+ chunks) should clear the endpoint's retransmission count and restart
+ the T2-shutdown timer, giving its peer ample opportunity to transmit
+ all of its queued DATA chunks that have not yet been sent.
+
+ Upon reception of the SHUTDOWN, the peer endpoint shall
+
+ - enter the SHUTDOWN-RECEIVED state,
+
+ - stop accepting new data from its SCTP user, and
+
+ - verify, by checking the Cumulative TSN Ack field of the chunk,
+ that all its outstanding DATA chunks have been received by the
+ SHUTDOWN sender.
+
+ Once an endpoint has reached the SHUTDOWN-RECEIVED state, it MUST NOT
+ send a SHUTDOWN in response to a ULP request, and should discard
+ subsequent SHUTDOWN chunks.
+
+ If there are still outstanding DATA chunks left, the SHUTDOWN
+ receiver MUST continue to follow normal data transmission procedures
+ defined in Section 6, until all outstanding DATA chunks are
+ acknowledged; however, the SHUTDOWN receiver MUST NOT accept new data
+ from its SCTP user.
+
+ While in the SHUTDOWN-SENT state, the SHUTDOWN sender MUST
+ immediately respond to each received packet containing one or more
+ DATA chunks with a SHUTDOWN chunk and restart the T2-shutdown timer.
+ If a SHUTDOWN chunk by itself cannot acknowledge all of the received
+ DATA chunks (i.e., there are TSNs that can be acknowledged that are
+ larger than the cumulative TSN, and thus gaps exist in the TSN
+ sequence), or if duplicate TSNs have been received, then a SACK chunk
+ MUST also be sent.
+
+ The sender of the SHUTDOWN MAY also start an overall guard timer
+ 'T5-shutdown-guard' to bound the overall time for the shutdown
+ sequence. At the expiration of this timer, the sender SHOULD abort
+ the association by sending an ABORT chunk. If the 'T5-shutdown-
+ guard' timer is used, it SHOULD be set to the recommended value of 5
+ times 'RTO.Max'.
+
+ If the receiver of the SHUTDOWN has no more outstanding DATA chunks,
+ the SHUTDOWN receiver MUST send a SHUTDOWN ACK and start a T2-
+
+
+
+Stewart Standards Track [Page 108]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ shutdown timer of its own, entering the SHUTDOWN-ACK-SENT state. If
+ the timer expires, the endpoint must resend the SHUTDOWN ACK.
+
+ The sender of the SHUTDOWN ACK should limit the number of
+ retransmissions of the SHUTDOWN ACK chunk to the protocol parameter
+ 'Association.Max.Retrans'. If this threshold is exceeded, the
+ endpoint should destroy the TCB and may report the peer endpoint
+ unreachable to the upper layer (and thus the association enters the
+ CLOSED state).
+
+ Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall stop
+ the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its peer,
+ and remove all record of the association.
+
+ Upon reception of the SHUTDOWN COMPLETE chunk, the endpoint will
+ verify that it is in the SHUTDOWN-ACK-SENT state; if it is not, the
+ chunk should be discarded. If the endpoint is in the SHUTDOWN-ACK-
+ SENT state, the endpoint should stop the T2-shutdown timer and remove
+ all knowledge of the association (and thus the association enters the
+ CLOSED state).
+
+ An endpoint SHOULD ensure that all its outstanding DATA chunks have
+ been acknowledged before initiating the shutdown procedure.
+
+ An endpoint should reject any new data request from its upper layer
+ if it is in the SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
+ or SHUTDOWN-ACK-SENT state.
+
+ If an endpoint is in the SHUTDOWN-ACK-SENT state and receives an INIT
+ chunk (e.g., if the SHUTDOWN COMPLETE was lost) with source and
+ destination transport addresses (either in the IP addresses or in the
+ INIT chunk) that belong to this association, it should discard the
+ INIT chunk and retransmit the SHUTDOWN ACK chunk.
+
+ Note: Receipt of an INIT with the same source and destination IP
+ addresses as used in transport addresses assigned to an endpoint but
+ with a different port number indicates the initialization of a
+ separate association.
+
+ The sender of the INIT or COOKIE ECHO should respond to the receipt
+ of a SHUTDOWN ACK with a stand-alone SHUTDOWN COMPLETE in an SCTP
+ packet with the Verification Tag field of its common header set to
+ the same tag that was received in the SHUTDOWN ACK packet. This is
+ considered an Out of the Blue packet as defined in Section 8.4. The
+ sender of the INIT lets T1-init continue running and remains in the
+ COOKIE-WAIT or COOKIE-ECHOED state. Normal T1-init timer expiration
+ will cause the INIT or COOKIE chunk to be retransmitted and thus
+ start a new association.
+
+
+
+Stewart Standards Track [Page 109]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ If a SHUTDOWN is received in the COOKIE-WAIT or COOKIE ECHOED state,
+ the SHUTDOWN chunk SHOULD be silently discarded.
+
+ If an endpoint is in the SHUTDOWN-SENT state and receives a SHUTDOWN
+ chunk from its peer, the endpoint shall respond immediately with a
+ SHUTDOWN ACK to its peer, and move into the SHUTDOWN-ACK-SENT state
+ restarting its T2-shutdown timer.
+
+ If an endpoint is in the SHUTDOWN-ACK-SENT state and receives a
+ SHUTDOWN ACK, it shall stop the T2-shutdown timer, send a SHUTDOWN
+ COMPLETE chunk to its peer, and remove all record of the association.
+
+10. Interface with Upper Layer
+
+ The Upper Layer Protocols (ULPs) shall request services by passing
+ primitives to SCTP and shall receive notifications from SCTP for
+ various events.
+
+ The primitives and notifications described in this section should be
+ used as a guideline for implementing SCTP. The following functional
+ description of ULP interface primitives is shown for illustrative
+ purposes. Different SCTP implementations may have different ULP
+ interfaces. However, all SCTPs must provide a certain minimum set of
+ services to guarantee that all SCTP implementations can support the
+ same protocol hierarchy.
+
+10.1. ULP-to-SCTP
+
+ The following sections functionally characterize a ULP/SCTP
+ interface. The notation used is similar to most procedure or
+ function calls in high-level languages.
+
+ The ULP primitives described below specify the basic functions that
+ SCTP must perform to support inter-process communication. Individual
+ implementations must define their own exact format, and may provide
+ combinations or subsets of the basic functions in single calls.
+
+ A) Initialize
+
+ Format: INITIALIZE ([local port],[local eligible address list])->
+ local SCTP instance name
+
+ This primitive allows SCTP to initialize its internal data structures
+ and allocate necessary resources for setting up its operation
+ environment. Once SCTP is initialized, ULP can communicate directly
+ with other endpoints without re-invoking this primitive.
+
+ SCTP will return a local SCTP instance name to the ULP.
+
+
+
+Stewart Standards Track [Page 110]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Mandatory attributes:
+
+ None.
+
+ Optional attributes:
+
+ The following types of attributes may be passed along with the
+ primitive:
+
+ o local port - SCTP port number, if ULP wants it to be specified.
+
+ o local eligible address list - an address list that the local SCTP
+ endpoint should bind. By default, if an address list is not
+ included, all IP addresses assigned to the host should be used by
+ the local endpoint.
+
+ IMPLEMENTATION NOTE: If this optional attribute is supported by an
+ implementation, it will be the responsibility of the implementation
+ to enforce that the IP source address field of any SCTP packets sent
+ out by this endpoint contains one of the IP addresses indicated in
+ the local eligible address list.
+
+ B) Associate
+
+ Format: ASSOCIATE(local SCTP instance name,
+ destination transport addr, outbound stream count)
+ -> association id [,destination transport addr list]
+ [,outbound stream count]
+
+ This primitive allows the upper layer to initiate an association to a
+ specific peer endpoint.
+
+ The peer endpoint shall be specified by one of the transport
+ addresses that defines the endpoint (see Section 1.3). If the local
+ SCTP instance has not been initialized, the ASSOCIATE is considered
+ an error.
+
+ An association id, which is a local handle to the SCTP association,
+ will be returned on successful establishment of the association. If
+ SCTP is not able to open an SCTP association with the peer endpoint,
+ an error is returned.
+
+ Other association parameters may be returned, including the complete
+ destination transport addresses of the peer as well as the outbound
+ stream count of the local endpoint. One of the transport addresses
+ from the returned destination addresses will be selected by the local
+ endpoint as default primary path for sending SCTP packets to this
+ peer. The returned "destination transport addr list" can be used by
+
+
+
+Stewart Standards Track [Page 111]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ the ULP to change the default primary path or to force sending a
+ packet to a specific transport address.
+
+ IMPLEMENTATION NOTE: If ASSOCIATE primitive is implemented as a
+ blocking function call, the ASSOCIATE primitive can return
+ association parameters in addition to the association id upon
+ successful establishment. If ASSOCIATE primitive is implemented as a
+ non-blocking call, only the association id shall be returned and
+ association parameters shall be passed using the COMMUNICATION UP
+ notification.
+
+ Mandatory attributes:
+
+ o local SCTP instance name - obtained from the INITIALIZE operation.
+
+ o destination transport addr - specified as one of the transport
+ addresses of the peer endpoint with which the association is to be
+ established.
+
+ o outbound stream count - the number of outbound streams the ULP
+ would like to open towards this peer endpoint.
+
+ Optional attributes:
+
+ None.
+
+ C) Shutdown
+
+ Format: SHUTDOWN(association id)
+ -> result
+
+ Gracefully closes an association. Any locally queued user data will
+ be delivered to the peer. The association will be terminated only
+ after the peer acknowledges all the SCTP packets sent. A success
+ code will be returned on successful termination of the association.
+ If attempting to terminate the association results in a failure, an
+ error code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ Optional attributes:
+
+ None.
+
+
+
+
+
+
+Stewart Standards Track [Page 112]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ D) Abort
+
+ Format: ABORT(association id [, Upper Layer Abort Reason]) ->
+ result
+
+ Ungracefully closes an association. Any locally queued user data
+ will be discarded, and an ABORT chunk is sent to the peer. A success
+ code will be returned on successful abort of the association. If
+ attempting to abort the association results in a failure, an error
+ code shall be returned.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ Optional attributes:
+
+ o Upper Layer Abort Reason - reason of the abort to be passed to the
+ peer.
+
+ None.
+
+ E) Send
+
+ Format: SEND(association id, buffer address, byte count [,context]
+ [,stream id] [,life time] [,destination transport address]
+ [,unordered flag] [,no-bundle flag] [,payload protocol-id] )
+ -> result
+
+ This is the main method to send user data via SCTP.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o buffer address - the location where the user message to be
+ transmitted is stored.
+
+ o byte count - the size of the user data in number of bytes.
+
+ Optional attributes:
+
+ o context - an optional 32-bit integer that will be carried in the
+ sending failure notification to the ULP if the transportation of
+ this user message fails.
+
+ o stream id - to indicate which stream to send the data on. If not
+ specified, stream 0 will be used.
+
+
+
+Stewart Standards Track [Page 113]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o life time - specifies the life time of the user data. The user
+ data will not be sent by SCTP after the life time expires. This
+ parameter can be used to avoid efforts to transmit stale user
+ messages. SCTP notifies the ULP if the data cannot be initiated
+ to transport (i.e., sent to the destination via SCTP's send
+ primitive) within the life time variable. However, the user data
+ will be transmitted if SCTP has attempted to transmit a chunk
+ before the life time expired.
+
+ IMPLEMENTATION NOTE: In order to better support the data life time
+ option, the transmitter may hold back the assigning of the TSN number
+ to an outbound DATA chunk to the last moment. And, for
+ implementation simplicity, once a TSN number has been assigned the
+ sender should consider the send of this DATA chunk as committed,
+ overriding any life time option attached to the DATA chunk.
+
+ o destination transport address - specified as one of the
+ destination transport addresses of the peer endpoint to which this
+ packet should be sent. Whenever possible, SCTP should use this
+ destination transport address for sending the packets, instead of
+ the current primary path.
+
+ o unordered flag - this flag, if present, indicates that the user
+ would like the data delivered in an unordered fashion to the peer
+ (i.e., the U flag is set to 1 on all DATA chunks carrying this
+ message).
+
+ o no-bundle flag - instructs SCTP not to bundle this user data with
+ other outbound DATA chunks. SCTP MAY still bundle even when this
+ flag is present, when faced with network congestion.
+
+ o payload protocol-id - a 32-bit unsigned integer that is to be
+ passed to the peer indicating the type of payload protocol data
+ being transmitted. This value is passed as opaque data by SCTP.
+
+ F) Set Primary
+
+ Format: SETPRIMARY(association id, destination transport address,
+ [source transport address] )
+ -> result
+
+ Instructs the local SCTP to use the specified destination transport
+ address as the primary path for sending packets.
+
+ The result of attempting this operation shall be returned. If the
+ specified destination transport address is not present in the
+ "destination transport address list" returned earlier in an associate
+ command or communication up notification, an error shall be returned.
+
+
+
+Stewart Standards Track [Page 114]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - specified as one of the transport
+ addresses of the peer endpoint, which should be used as the
+ primary address for sending packets. This overrides the current
+ primary address information maintained by the local SCTP endpoint.
+
+ Optional attributes:
+
+ o source transport address - optionally, some implementations may
+ allow you to set the default source address placed in all outgoing
+ IP datagrams.
+
+ G) Receive
+
+ Format: RECEIVE(association id, buffer address, buffer size
+ [,stream id])
+ -> byte count [,transport address] [,stream id] [,stream sequence
+ number] [,partial flag] [,delivery number] [,payload protocol-id]
+
+ This primitive shall read the first user message in the SCTP in-queue
+ into the buffer specified by ULP, if there is one available. The
+ size of the message read, in bytes, will be returned. It may,
+ depending on the specific implementation, also return other
+ information such as the sender's address, the stream id on which it
+ is received, whether there are more messages available for retrieval,
+ etc. For ordered messages, their Stream Sequence Number may also be
+ returned.
+
+ Depending upon the implementation, if this primitive is invoked when
+ no message is available the implementation should return an
+ indication of this condition or should block the invoking process
+ until data does become available.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - to indicate which stream to receive the data on.
+
+
+
+Stewart Standards Track [Page 115]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o Stream Sequence Number - the Stream Sequence Number assigned by
+ the sending SCTP peer.
+
+ o partial flag - if this returned flag is set to 1, then this
+ Receive contains a partial delivery of the whole message. When
+ this flag is set, the stream id and Stream Sequence Number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this Stream Sequence
+ Number.
+
+ o payload protocol-id - a 32-bit unsigned integer that is received
+ from the peer indicating the type of payload protocol of the
+ received data. This value is passed as opaque data by SCTP.
+
+ H) Status
+
+ Format: STATUS(association id)
+ -> status data
+
+ This primitive should return a data block containing the following
+ information:
+
+ association connection state,
+ destination transport address list,
+ destination transport address reachability states,
+ current receiver window size,
+ current congestion window sizes,
+ number of unacknowledged DATA chunks,
+ number of DATA chunks pending receipt,
+ primary path,
+ most recent SRTT on primary path,
+ RTO on primary path,
+ SRTT and RTO on other destination addresses, etc.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ Optional attributes:
+
+ None.
+
+ I) Change Heartbeat
+
+ Format: CHANGE HEARTBEAT(association id,
+ destination transport address, new state [,interval])
+ -> result
+
+
+
+
+Stewart Standards Track [Page 116]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Instructs the local endpoint to enable or disable heartbeat on the
+ specified destination transport address.
+
+ The result of attempting this operation shall be returned.
+
+ Note: Even when enabled, heartbeat will not take place if the
+ destination transport address is not idle.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - specified as one of the transport
+ addresses of the peer endpoint.
+
+ o new state - the new state of heartbeat for this destination
+ transport address (either enabled or disabled).
+
+ Optional attributes:
+
+ o interval - if present, indicates the frequency of the heartbeat if
+ this is to enable heartbeat on a destination transport address.
+ This value is added to the RTO of the destination transport
+ address. This value, if present, affects all destinations.
+
+ J) Request HeartBeat
+
+ Format: REQUESTHEARTBEAT(association id, destination transport
+ address)
+ -> result
+
+ Instructs the local endpoint to perform a HeartBeat on the specified
+ destination transport address of the given association. The returned
+ result should indicate whether the transmission of the HEARTBEAT
+ chunk to the destination address is successful.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - the transport address of the
+ association on which a heartbeat should be issued.
+
+ K) Get SRTT Report
+
+ Format: GETSRTTREPORT(association id,
+ destination transport address)
+ -> srtt result
+
+
+
+Stewart Standards Track [Page 117]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Instructs the local SCTP to report the current SRTT measurement on
+ the specified destination transport address of the given association.
+ The returned result can be an integer containing the most recent SRTT
+ in milliseconds.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - the transport address of the
+ association on which the SRTT measurement is to be reported.
+
+ L) Set Failure Threshold
+
+ Format: SETFAILURETHRESHOLD(association id, destination transport
+ address, failure threshold)
+
+ -> result
+
+ This primitive allows the local SCTP to customize the reachability
+ failure detection threshold 'Path.Max.Retrans' for the specified
+ destination address.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - the transport address of the
+ association on which the failure detection threshold is to be set.
+
+ o failure threshold - the new value of 'Path.Max.Retrans' for the
+ destination address.
+
+ M) Set Protocol Parameters
+
+ Format: SETPROTOCOLPARAMETERS(association id,
+ [,destination transport address,]
+ protocol parameter list)
+ -> result
+
+ This primitive allows the local SCTP to customize the protocol
+ parameters.
+
+ Mandatory attributes:
+
+ o association id - local handle to the SCTP association.
+
+
+
+
+
+Stewart Standards Track [Page 118]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o protocol parameter list - the specific names and values of the
+ protocol parameters (e.g., Association.Max.Retrans; see Section
+ 15) that the SCTP user wishes to customize.
+
+ Optional attributes:
+
+ o destination transport address - some of the protocol parameters
+ may be set on a per destination transport address basis.
+
+ N) Receive Unsent Message
+
+ Format: RECEIVE_UNSENT(data retrieval id, buffer address, buffer
+ size [,stream id] [, stream sequence number] [,partial
+ flag] [,payload protocol-id])
+
+ o data retrieval id - the identification passed to the ULP in the
+ failure notification.
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - this is a return value that is set to indicate which
+ stream the data was sent to.
+
+ o Stream Sequence Number - this value is returned indicating the
+ Stream Sequence Number that was associated with the message.
+
+ o partial flag - if this returned flag is set to 1, then this
+ message is a partial delivery of the whole message. When this
+ flag is set, the stream id and Stream Sequence Number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this Stream Sequence
+ Number.
+
+ o payload protocol-id - The 32 bit unsigned integer that was sent to
+ be sent to the peer indicating the type of payload protocol of the
+ received data.
+
+ o Receive Unacknowledged Message
+
+ Format: RECEIVE_UNACKED(data retrieval id, buffer address, buffer
+ size, [,stream id] [, stream sequence number] [,partial
+ flag] [,payload protocol-id])
+
+
+
+
+Stewart Standards Track [Page 119]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o data retrieval id - the identification passed to the ULP in the
+ failure notification.
+
+ o buffer address - the memory location indicated by the ULP to store
+ the received message.
+
+ o buffer size - the maximum size of data to be received, in bytes.
+
+ Optional attributes:
+
+ o stream id - this is a return value that is set to indicate which
+ stream the data was sent to.
+
+ o Stream Sequence Number - this value is returned indicating the
+ Stream Sequence Number that was associated with the message.
+
+ o partial flag - if this returned flag is set to 1, then this
+ message is a partial delivery of the whole message. When this
+ flag is set, the stream id and Stream Sequence Number MUST
+ accompany this receive. When this flag is set to 0, it indicates
+ that no more deliveries will be received for this Stream Sequence
+ Number.
+
+ o payload protocol-id - the 32-bit unsigned integer that was sent to
+ the peer indicating the type of payload protocol of the received
+ data.
+
+ P) Destroy SCTP Instance
+
+ Format: DESTROY(local SCTP instance name)
+
+ o local SCTP instance name - this is the value that was passed to
+ the application in the initialize primitive and it indicates which
+ SCTP instance is to be destroyed.
+
+10.2. SCTP-to-ULP
+
+ It is assumed that the operating system or application environment
+ provides a means for the SCTP to asynchronously signal the ULP
+ process. When SCTP does signal a ULP process, certain information is
+ passed to the ULP.
+
+ IMPLEMENTATION NOTE: In some cases, this may be done through a
+ separate socket or error channel.
+
+
+
+
+
+
+
+Stewart Standards Track [Page 120]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ A) DATA ARRIVE notification
+
+ SCTP shall invoke this notification on the ULP when a user message is
+ successfully received and ready for retrieval.
+
+ The following may optionally be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o stream id - to indicate which stream the data is received on.
+
+ B) SEND FAILURE notification
+
+ If a message cannot be delivered, SCTP shall invoke this notification
+ on the ULP.
+
+ The following may optionally be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o data retrieval id - an identification used to retrieve unsent and
+ unacknowledged data.
+
+ o cause code - indicating the reason of the failure, e.g., size too
+ large, message life time expiration, etc.
+
+ o context - optional information associated with this message (see D
+ in Section 10.1).
+
+ C) NETWORK STATUS CHANGE notification
+
+ When a destination transport address is marked inactive (e.g., when
+ SCTP detects a failure) or marked active (e.g., when SCTP detects a
+ recovery), SCTP shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o destination transport address - this indicates the destination
+ transport address of the peer endpoint affected by the change.
+
+ o new-status - this indicates the new status.
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 121]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ D) COMMUNICATION UP notification
+
+ This notification is used when SCTP becomes ready to send or receive
+ user messages, or when a lost communication to an endpoint is
+ restored.
+
+ IMPLEMENTATION NOTE: If the ASSOCIATE primitive is implemented as a
+ blocking function call, the association parameters are returned as a
+ result of the ASSOCIATE primitive itself. In that case,
+ COMMUNICATION UP notification is optional at the association
+ initiator's side.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o status - This indicates what type of event has occurred.
+
+ o destination transport address list - the complete set of
+ transport addresses of the peer.
+
+ o outbound stream count - the maximum number of streams allowed to
+ be used in this association by the ULP.
+
+ o inbound stream count - the number of streams the peer endpoint
+ has requested with this association (this may not be the same
+ number as 'outbound stream count').
+
+ E) COMMUNICATION LOST notification
+
+ When SCTP loses communication to an endpoint completely (e.g., via
+ Heartbeats) or detects that the endpoint has performed an abort
+ operation, it shall invoke this notification on the ULP.
+
+ The following shall be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o status - this indicates what type of event has occurred; the
+ status may indicate that a failure OR a normal
+ termination event occurred in response to a shutdown or
+ abort request.
+
+ The following may be passed with the notification:
+
+ o data retrieval id - an identification used to retrieve unsent and
+ unacknowledged data.
+
+
+
+
+Stewart Standards Track [Page 122]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ o last-acked - the TSN last acked by that peer endpoint.
+
+ o last-sent - the TSN last sent to that peer endpoint.
+
+ o Upper Layer Abort Reason - the abort reason specified in case of
+ a user-initiated abort.
+
+ F) COMMUNICATION ERROR notification
+
+ When SCTP receives an ERROR chunk from its peer and decides to notify
+ its ULP, it can invoke this notification on the ULP.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ o error info - this indicates the type of error and optionally some
+ additional information received through the ERROR chunk.
+
+ G) RESTART notification
+
+ When SCTP detects that the peer has restarted, it may send this
+ notification to its ULP.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+ H) SHUTDOWN COMPLETE notification
+
+ When SCTP completes the shutdown procedures (Section 9.2), this
+ notification is passed to the upper layer.
+
+ The following can be passed with the notification:
+
+ o association id - local handle to the SCTP association.
+
+11. Security Considerations
+
+11.1. Security Objectives
+
+ As a common transport protocol designed to reliably carry time-
+ sensitive user messages, such as billing or signaling messages for
+ telephony services, between two networked endpoints, SCTP has the
+ following security objectives.
+
+ - availability of reliable and timely data transport services
+
+
+
+
+Stewart Standards Track [Page 123]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ - integrity of the user-to-user information carried by SCTP
+
+11.2. SCTP Responses to Potential Threats
+
+ SCTP may potentially be used in a wide variety of risk situations.
+ It is important for operators of systems running SCTP to analyze
+ their particular situations and decide on the appropriate counter-
+ measures.
+
+ Operators of systems running SCTP should consult [RFC2196] for
+ guidance in securing their site.
+
+11.2.1. Countering Insider Attacks
+
+ The principles of [RFC2196] should be applied to minimize the risk of
+ theft of information or sabotage by insiders. Such procedures
+ include publication of security policies, control of access at the
+ physical, software, and network levels, and separation of services.
+
+11.2.2. Protecting against Data Corruption in the Network
+
+ Where the risk of undetected errors in datagrams delivered by the
+ lower-layer transport services is considered to be too great,
+ additional integrity protection is required. If this additional
+ protection were provided in the application layer, the SCTP header
+ would remain vulnerable to deliberate integrity attacks. While the
+ existing SCTP mechanisms for detection of packet replays are
+ considered sufficient for normal operation, stronger protections are
+ needed to protect SCTP when the operating environment contains
+ significant risk of deliberate attacks from a sophisticated
+ adversary.
+
+ The SCTP Authentication extension SCTP-AUTH [RFC4895] MAY be used
+ when the threat environment requires stronger integrity protections,
+ but does not require confidentiality.
+
+11.2.3. Protecting Confidentiality
+
+ In most cases, the risk of breach of confidentiality applies to the
+ signaling data payload, not to the SCTP or lower-layer protocol
+ overheads. If that is true, encryption of the SCTP user data only
+ might be considered. As with the supplementary checksum service,
+ user data encryption MAY be performed by the SCTP user application.
+ Alternately, the user application MAY use an implementation-specific
+ API to request that the IP Encapsulating Security Payload (ESP)
+ [RFC4303] be used to provide confidentiality and integrity.
+
+
+
+
+
+Stewart Standards Track [Page 124]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Particularly for mobile users, the requirement for confidentiality
+ might include the masking of IP addresses and ports. In this case,
+ ESP SHOULD be used instead of application-level confidentiality. If
+ ESP is used to protect confidentiality of SCTP traffic, an ESP
+ cryptographic transform that includes cryptographic integrity
+ protection MUST be used, because if there is a confidentiality threat
+ there will also be a strong integrity threat.
+
+ Whenever ESP is in use, application-level encryption is not generally
+ required.
+
+ Regardless of where confidentiality is provided, the Internet Key
+ Exchange Protocol version 2 (IKEv2) [RFC4306] SHOULD be used for key
+ management.
+
+ Operators should consult [RFC4301] for more information on the
+ security services available at and immediately above the Internet
+ Protocol layer.
+
+11.2.4. Protecting against Blind Denial-of-Service Attacks
+
+ A blind attack is one where the attacker is unable to intercept or
+ otherwise see the content of data flows passing to and from the
+ target SCTP node. Blind denial-of-service attacks may take the form
+ of flooding, masquerade, or improper monopolization of services.
+
+11.2.4.1. Flooding
+
+ The objective of flooding is to cause loss of service and incorrect
+ behavior at target systems through resource exhaustion, interference
+ with legitimate transactions, and exploitation of buffer-related
+ software bugs. Flooding may be directed either at the SCTP node or
+ at resources in the intervening IP Access Links or the Internet.
+ Where the latter entities are the target, flooding will manifest
+ itself as loss of network services, including potentially the breach
+ of any firewalls in place.
+
+ In general, protection against flooding begins at the equipment
+ design level, where it includes measures such as:
+
+ - avoiding commitment of limited resources before determining that
+ the request for service is legitimate.
+
+ - giving priority to completion of processing in progress over the
+ acceptance of new work.
+
+ - identification and removal of duplicate or stale queued requests
+ for service.
+
+
+
+Stewart Standards Track [Page 125]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ - not responding to unexpected packets sent to non-unicast
+ addresses.
+
+ Network equipment should be capable of generating an alarm and log if
+ a suspicious increase in traffic occurs. The log should provide
+ information such as the identity of the incoming link and source
+ address(es) used, which will help the network or SCTP system operator
+ to take protective measures. Procedures should be in place for the
+ operator to act on such alarms if a clear pattern of abuse emerges.
+
+ The design of SCTP is resistant to flooding attacks, particularly in
+ its use of a four-way startup handshake, its use of a cookie to defer
+ commitment of resources at the responding SCTP node until the
+ handshake is completed, and its use of a Verification Tag to prevent
+ insertion of extraneous packets into the flow of an established
+ association.
+
+ The IP Authentication Header and Encapsulating Security Payload might
+ be useful in reducing the risk of certain kinds of denial-of-service
+ attacks.
+
+ The use of the host name feature in the INIT chunk could be used to
+ flood a target DNS server. A large backlog of DNS queries, resolving
+ the host name received in the INIT chunk to IP addresses, could be
+ accomplished by sending INITs to multiple hosts in a given domain.
+ In addition, an attacker could use the host name feature in an
+ indirect attack on a third party by sending large numbers of INITs to
+ random hosts containing the host name of the target. In addition to
+ the strain on DNS resources, this could also result in large numbers
+ of INIT ACKs being sent to the target. One method to protect against
+ this type of attack is to verify that the IP addresses received from
+ DNS include the source IP address of the original INIT. If the list
+ of IP addresses received from DNS does not include the source IP
+ address of the INIT, the endpoint MAY silently discard the INIT.
+ This last option will not protect against the attack against the DNS.
+
+11.2.4.2. Blind Masquerade
+
+ Masquerade can be used to deny service in several ways:
+
+ - by tying up resources at the target SCTP node to which the
+ impersonated node has limited access. For example, the target
+ node may by policy permit a maximum of one SCTP association with
+ the impersonated SCTP node. The masquerading attacker may attempt
+ to establish an association purporting to come from the
+ impersonated node so that the latter cannot do so when it requires
+ it.
+
+
+
+
+Stewart Standards Track [Page 126]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ - by deliberately allowing the impersonation to be detected, thereby
+ provoking counter-measures that cause the impersonated node to be
+ locked out of the target SCTP node.
+
+ - by interfering with an established association by inserting
+ extraneous content such as a SHUTDOWN request.
+
+ SCTP reduces the risk of blind masquerade attacks through IP spoofing
+ by use of the four-way startup handshake. Because the initial
+ exchange is memory-less, no lockout mechanism is triggered by blind
+ masquerade attacks. In addition, the INIT ACK containing the State
+ Cookie is transmitted back to the IP address from which it received
+ the INIT. Thus, the attacker would not receive the INIT ACK
+ containing the State Cookie. SCTP protects against insertion of
+ extraneous packets into the flow of an established association by use
+ of the Verification Tag.
+
+ Logging of received INIT requests and abnormalities such as
+ unexpected INIT ACKs might be considered as a way to detect patterns
+ of hostile activity. However, the potential usefulness of such
+ logging must be weighed against the increased SCTP startup processing
+ it implies, rendering the SCTP node more vulnerable to flooding
+ attacks. Logging is pointless without the establishment of operating
+ procedures to review and analyze the logs on a routine basis.
+
+11.2.4.3. Improper Monopolization of Services
+
+ Attacks under this heading are performed openly and legitimately by
+ the attacker. They are directed against fellow users of the target
+ SCTP node or of the shared resources between the attacker and the
+ target node. Possible attacks include the opening of a large number
+ of associations between the attacker's node and the target, or
+ transfer of large volumes of information within a legitimately
+ established association.
+
+ Policy limits should be placed on the number of associations per
+ adjoining SCTP node. SCTP user applications should be capable of
+ detecting large volumes of illegitimate or "no-op" messages within a
+ given association and either logging or terminating the association
+ as a result, based on local policy.
+
+11.3. SCTP Interactions with Firewalls
+
+ It is helpful for some firewalls if they can inspect just the first
+ fragment of a fragmented SCTP packet and unambiguously determine
+ whether it corresponds to an INIT chunk (for further information,
+ please refer to [RFC1858]). Accordingly, we stress the requirements,
+ stated in Section 3.1, that (1) an INIT chunk MUST NOT be bundled
+
+
+
+Stewart Standards Track [Page 127]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ with any other chunk in a packet, and (2) a packet containing an INIT
+ chunk MUST have a zero Verification Tag. Furthermore, we require
+ that the receiver of an INIT chunk MUST enforce these rules by
+ silently discarding an arriving packet with an INIT chunk that is
+ bundled with other chunks or has a non-zero verification tag and
+ contains an INIT-chunk.
+
+11.4. Protection of Non-SCTP-Capable Hosts
+
+ To provide a non-SCTP-capable host with the same level of protection
+ against attacks as for SCTP-capable ones, all SCTP stacks MUST
+ implement the ICMP handling described in Appendix C.
+
+ When an SCTP stack receives a packet containing multiple control or
+ DATA chunks and the processing of the packet requires the sending of
+ multiple chunks in response, the sender of the response chunk(s) MUST
+ NOT send more than one packet. If bundling is supported, multiple
+ response chunks that fit into a single packet MAY be bundled together
+ into one single response packet. If bundling is not supported, then
+ the sender MUST NOT send more than one response chunk and MUST
+ discard all other responses. Note that this rule does NOT apply to a
+ SACK chunk, since a SACK chunk is, in itself, a response to DATA and
+ a SACK does not require a response of more DATA.
+
+ An SCTP implementation SHOULD abort the association if it receives a
+ SACK acknowledging a TSN that has not been sent.
+
+ An SCTP implementation that receives an INIT that would require a
+ large packet in response, due to the inclusion of multiple ERROR
+ parameters, MAY (at its discretion) elect to omit some or all of the
+ ERROR parameters to reduce the size of the INIT ACK. Due to a
+ combination of the size of the COOKIE parameter and the number of
+ addresses a receiver of an INIT may be indicating to a peer, it is
+ always possible that the INIT ACK will be larger than the original
+ INIT. An SCTP implementation SHOULD attempt to make the INIT ACK as
+ small as possible to reduce the possibility of byte amplification
+ attacks.
+
+12. Network Management Considerations
+
+ The MIB module for SCTP defined in [RFC3873] applies for the version
+ of the protocol specified in this document.
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 128]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+13. Recommended Transmission Control Block (TCB) Parameters
+
+ This section details a recommended set of parameters that should be
+ contained within the TCB for an implementation. This section is for
+ illustrative purposes and should not be deemed as requirements on an
+ implementation or as an exhaustive list of all parameters inside an
+ SCTP TCB. Each implementation may need its own additional parameters
+ for optimization.
+
+13.1. Parameters Necessary for the SCTP Instance
+
+ Associations: A list of current associations and mappings to the data
+ consumers for each association. This may be in the
+ form of a hash table or other implementation-dependent
+ structure. The data consumers may be process
+ identification information such as file descriptors,
+ named pipe pointer, or table pointers dependent on how
+ SCTP is implemented.
+
+ Secret Key: A secret key used by this endpoint to compute the MAC.
+ This SHOULD be a cryptographic quality random number
+ with a sufficient length. Discussion in RFC 4086 can
+ be helpful in selection of the key.
+
+ Address List: The list of IP addresses that this instance has bound.
+ This information is passed to one's peer(s) in INIT and
+ INIT ACK chunks.
+
+ SCTP Port: The local SCTP port number to which the endpoint is
+ bound.
+
+13.2. Parameters Necessary per Association (i.e., the TCB)
+
+ Peer : Tag value to be sent in every packet and is received
+ Verification: in the INIT or INIT ACK chunk.
+ Tag :
+
+ My : Tag expected in every inbound packet and sent in the
+ Verification: INIT or INIT ACK chunk.
+ Tag :
+
+ State : A state variable indicating what state the association
+ : is in, i.e., COOKIE-WAIT, COOKIE-ECHOED, ESTABLISHED,
+ : SHUTDOWN-PENDING, SHUTDOWN-SENT, SHUTDOWN-RECEIVED,
+ : SHUTDOWN-ACK-SENT.
+
+ Note: No "CLOSED" state is illustrated since if a
+ association is "CLOSED" its TCB SHOULD be removed.
+
+
+
+Stewart Standards Track [Page 129]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Peer : A list of SCTP transport addresses to which the peer
+ Transport : is bound. This information is derived from the INIT or
+ Address : INIT ACK and is used to associate an inbound packet
+ List : with a given association. Normally, this information
+ : is hashed or keyed for quick lookup and access of the
+ : TCB.
+
+ Primary : This is the current primary destination transport
+ Path : address of the peer endpoint. It may also specify a
+ : source transport address on this endpoint.
+
+ Overall : The overall association error count.
+ Error Count :
+
+ Overall : The threshold for this association that if the Overall
+ Error : Error Count reaches will cause this association to be
+ Threshold : torn down.
+
+ Peer Rwnd : Current calculated value of the peer's rwnd.
+
+ Next TSN : The next TSN number to be assigned to a new DATA chunk.
+ : This is sent in the INIT or INIT ACK chunk to the peer
+ : and incremented each time a DATA chunk is assigned a
+ : TSN (normally just prior to transmit or during
+ : fragmentation).
+
+ Last Rcvd : This is the last TSN received in sequence. This value
+ TSN : is set initially by taking the peer's initial TSN,
+ : received in the INIT or INIT ACK chunk, and
+ : subtracting one from it.
+
+ Mapping : An array of bits or bytes indicating which out-of-
+ Array : order TSNs have been received (relative to the
+ : Last Rcvd TSN). If no gaps exist, i.e., no out-of-
+ : order packets have been received, this array will
+ : be set to all zero. This structure may be in the
+ : form of a circular buffer or bit array.
+
+ Ack State : This flag indicates if the next received packet
+ : is to be responded to with a SACK. This is initialized
+ : to 0. When a packet is received it is incremented.
+ : If this value reaches 2 or more, a SACK is sent and the
+ : value is reset to 0. Note: This is used only when no
+ : DATA chunks are received out of order. When DATA
+ : chunks are out of order, SACKs are not delayed (see
+ : Section 6).
+
+
+
+
+
+Stewart Standards Track [Page 130]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Inbound : An array of structures to track the inbound streams,
+ Streams : normally including the next sequence number expected
+ : and possibly the stream number.
+
+ Outbound : An array of structures to track the outbound streams,
+ Streams : normally including the next sequence number to
+ : be sent on the stream.
+
+ Reasm Queue : A reassembly queue.
+
+ Local : The list of local IP addresses bound in to this
+ Transport : association.
+ Address :
+ List :
+
+ Association : The smallest PMTU discovered for all of the
+ PMTU : peer's transport addresses.
+
+13.3. Per Transport Address Data
+
+ For each destination transport address in the peer's address list
+ derived from the INIT or INIT ACK chunk, a number of data elements
+ need to be maintained including:
+
+ Error Count : The current error count for this destination.
+
+ Error : Current error threshold for this destination, i.e.,
+ Threshold : what value marks the destination down if error count
+ : reaches this value.
+
+ cwnd : The current congestion window.
+
+ ssthresh : The current ssthresh value.
+
+ RTO : The current retransmission timeout value.
+
+ SRTT : The current smoothed round-trip time.
+
+ RTTVAR : The current RTT variation.
+
+ partial : The tracking method for increase of cwnd when in
+ bytes acked : congestion avoidance mode (see Section 7.2.2).
+
+ state : The current state of this destination, i.e., DOWN, UP,
+ : ALLOW-HB, NO-HEARTBEAT, etc.
+
+
+
+
+
+
+Stewart Standards Track [Page 131]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ PMTU : The current known path MTU.
+
+ Per : A timer used by each destination.
+ Destination :
+ Timer :
+
+ RTO-Pending : A flag used to track if one of the DATA chunks sent to
+ : this address is currently being used to compute an
+ : RTT. If this flag is 0, the next DATA chunk sent to
+ : this destination should be used to compute an RTT and
+ : this flag should be set. Every time the RTT
+ : calculation completes (i.e., the DATA chunk is SACK'd),
+ : clear this flag.
+
+ last-time : The time to which this destination was last sent.
+ : This can be to determine if a HEARTBEAT is needed.
+
+13.4. General Parameters Needed
+
+ Out Queue : A queue of outbound DATA chunks.
+
+ In Queue : A queue of inbound DATA chunks.
+
+14. IANA Considerations
+
+ SCTP defines three registries that IANA maintains:
+
+ - through definition of additional chunk types,
+ - through definition of additional parameter types, or
+ - through definition of additional cause codes within ERROR chunks.
+
+ SCTP requires that the IANA Port Numbers registry be opened for SCTP
+ port registrations, Section 14.5 describes how. An IESG-appointed
+ Expert Reviewer supports IANA in evaluating SCTP port allocation
+ requests.
+
+14.1. IETF-Defined Chunk Extension
+
+ The assignment of new chunk parameter type codes is done through an
+ IETF Consensus action, as defined in [RFC2434]. Documentation of the
+ chunk parameter MUST contain the following information:
+
+ a) A long and short name for the new chunk type.
+
+ b) A detailed description of the structure of the chunk, which MUST
+ conform to the basic structure defined in Section 3.2.
+
+
+
+
+
+Stewart Standards Track [Page 132]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ c) A detailed definition and description of intended use of each
+ field within the chunk, including the chunk flags if any.
+
+ d) A detailed procedural description of the use of the new chunk type
+ within the operation of the protocol.
+
+ The last chunk type (255) is reserved for future extension if
+ necessary.
+
+14.2. IETF-Defined Chunk Parameter Extension
+
+ The assignment of new chunk parameter type codes is done through an
+ IETF Consensus action as defined in [RFC2434]. Documentation of the
+ chunk parameter MUST contain the following information:
+
+ a) Name of the parameter type.
+
+ b) Detailed description of the structure of the parameter field.
+ This structure MUST conform to the general Type-Length-Value
+ format described in Section 3.2.1.
+
+ c) Detailed definition of each component of the parameter value.
+
+ d) Detailed description of the intended use of this parameter type,
+ and an indication of whether and under what circumstances multiple
+ instances of this parameter type may be found within the same
+ chunk.
+
+ e) Each parameter type MUST be unique across all chunks.
+
+14.3. IETF-Defined Additional Error Causes
+
+ Additional cause codes may be allocated in the range 11 to 65535
+ through a Specification Required action as defined in [RFC2434].
+ Provided documentation must include the following information:
+
+ a) Name of the error condition.
+
+ b) Detailed description of the conditions under which an SCTP
+ endpoint should issue an ERROR (or ABORT) with this cause code.
+
+ c) Expected action by the SCTP endpoint that receives an ERROR (or
+ ABORT) chunk containing this cause code.
+
+ d) Detailed description of the structure and content of data fields
+ that accompany this cause code.
+
+
+
+
+
+Stewart Standards Track [Page 133]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ The initial word (32 bits) of a cause code parameter MUST conform to
+ the format shown in Section 3.3.10, i.e.:
+
+ - first 2 bytes contain the cause code value
+ - last 2 bytes contain the length of the cause parameter.
+
+14.4. Payload Protocol Identifiers
+
+ Except for value 0, which is reserved by SCTP to indicate an
+ unspecified payload protocol identifier in a DATA chunk, SCTP will
+ not be responsible for standardizing or verifying any payload
+ protocol identifiers; SCTP simply receives the identifier from the
+ upper layer and carries it with the corresponding payload data.
+
+ The upper layer, i.e., the SCTP user, SHOULD standardize any specific
+ protocol identifier with IANA if it is so desired. The use of any
+ specific payload protocol identifier is out of the scope of SCTP.
+
+14.5. Port Numbers Registry
+
+ SCTP services may use contact port numbers to provide service to
+ unknown callers, as in TCP and UDP. IANA is therefore requested to
+ open the existing Port Numbers registry for SCTP using the following
+ rules, which we intend to mesh well with existing Port Numbers
+ registration procedures. An IESG-appointed Expert Reviewer supports
+ IANA in evaluating SCTP port allocation requests, according to the
+ procedure defined in [RFC2434].
+
+ Port numbers are divided into three ranges. The Well Known Ports are
+ those from 0 through 1023, the Registered Ports are those from 1024
+ through 49151, and the Dynamic and/or Private Ports are those from
+ 49152 through 65535. Well Known and Registered Ports are intended
+ for use by server applications that desire a default contact point on
+ a system. On most systems, Well Known Ports can only be used by
+ system (or root) processes or by programs executed by privileged
+ users, while Registered Ports can be used by ordinary user processes
+ or programs executed by ordinary users. Dynamic and/or Private Ports
+ are intended for temporary use, including client-side ports, out-of-
+ band negotiated ports, and application testing prior to registration
+ of a dedicated port; they MUST NOT be registered.
+
+ The Port Numbers registry should accept registrations for SCTP ports
+ in the Well Known Ports and Registered Ports ranges. Well Known and
+ Registered Ports SHOULD NOT be used without registration. Although
+ in some cases -- such as porting an application from TCP to SCTP --
+ it may seem natural to use an SCTP port before registration
+ completes, we emphasize that IANA will not guarantee registration of
+
+
+
+
+Stewart Standards Track [Page 134]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ particular Well Known and Registered Ports. Registrations should be
+ requested as early as possible.
+
+ Each port registration SHALL include the following information:
+
+ o A short port name, consisting entirely of letters (A-Z and a-z),
+ digits (0-9), and punctuation characters from "-_+./*" (not
+ including the quotes).
+
+ o The port number that is requested for registration.
+
+ o A short English phrase describing the port's purpose.
+
+ o Name and contact information for the person or entity performing
+ the registration, and possibly a reference to a document defining
+ the port's use. Registrations coming from IETF working groups
+ need only name the working group, but indicating a contact person
+ is recommended.
+
+ Registrants are encouraged to follow these guidelines when submitting
+ a registration.
+
+ o A port name SHOULD NOT be registered for more than one SCTP port
+ number.
+
+ o A port name registered for TCP MAY be registered for SCTP as well.
+ Any such registration SHOULD use the same port number as the
+ existing TCP registration.
+
+ o Concrete intent to use a port SHOULD precede port registration.
+ For example, existing TCP ports SHOULD NOT be registered in
+ advance of any intent to use those ports for SCTP.
+
+ This document registers the following ports. (These registrations
+ should be considered models to follow for future allocation
+ requests.)
+
+ discard 9/sctp Discard # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ The discard service, which accepts SCTP connections on port
+ 9, discards all incoming application data and sends no data
+ in response. Thus, SCTP's discard port is analogous to
+ TCP's discard port, and might be used to check the health
+ of an SCTP stack.
+
+
+
+
+
+Stewart Standards Track [Page 135]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ ftp-data 20/sctp FTP # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ ftp 21/sctp FTP # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ File Transfer Protocol (FTP) data (20) and control ports
+ (21).
+
+ ssh 22/sctp SSH # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ The Secure Shell (SSH) remote login service, which allows
+ secure shell logins to a host.
+
+ http 80/sctp HTTP # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ World Wide Web HTTP over SCTP.
+
+ bgp 179/sctp BGP # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ Border Gateway Protocol over SCTP.
+
+ https 443/sctp HTTPS # IETF TSVWG
+ # Randall Stewart <rrs@cisco.com>
+ # [RFC4960]
+
+ World Wide Web HTTP over TLS/SSL over SCTP.
+
+15. Suggested SCTP Protocol Parameter Values
+
+ The following protocol parameters are RECOMMENDED:
+
+ RTO.Initial - 3 seconds
+ RTO.Min - 1 second
+ RTO.Max - 60 seconds
+ Max.Burst - 4
+ RTO.Alpha - 1/8
+ RTO.Beta - 1/4
+ Valid.Cookie.Life - 60 seconds
+ Association.Max.Retrans - 10 attempts
+
+
+
+Stewart Standards Track [Page 136]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Path.Max.Retrans - 5 attempts (per destination address)
+ Max.Init.Retransmits - 8 attempts
+ HB.interval - 30 seconds
+ HB.Max.Burst - 1
+
+ IMPLEMENTATION NOTE: The SCTP implementation may allow ULP to
+ customize some of these protocol parameters (see Section 10).
+
+ Note: RTO.Min SHOULD be set as recommended above.
+
+16. Acknowledgements
+
+ An undertaking represented by this updated document is not a small
+ feat and represents the summation of the initial authors of RFC 2960:
+ Q. Xie, K. Morneault, C. Sharp, H. Schwarzbauer, T. Taylor, I.
+ Rytina, M. Kalla, L. Zhang, and V. Paxson.
+
+ Add to that, the comments from everyone who contributed to the
+ original RFC:
+
+ Mark Allman, R.J. Atkinson, Richard Band, Scott Bradner, Steve
+ Bellovin, Peter Butler, Ram Dantu, R. Ezhirpavai, Mike Fisk, Sally
+ Floyd, Atsushi Fukumoto, Matt Holdrege, Henry Houh, Christian
+ Huitema, Gary Lehecka, Jonathan Lee, David Lehmann, John Loughney,
+ Daniel Luan, Barry Nagelberg, Thomas Narten, Erik Nordmark, Lyndon
+ Ong, Shyamal Prasad, Kelvin Porter, Heinz Prantner, Jarno Rajahalme,
+ Raymond E. Reeves, Renee Revis, Ivan Arias Rodriguez, A. Sankar, Greg
+ Sidebottom, Brian Wyld, La Monte Yarroll, and many others for their
+ invaluable comments.
+
+ Then, add the authors of the SCTP implementor's guide, I. Arias-
+ Rodriguez, K. Poon, A. Caro, and M. Tuexen.
+
+ Then add to these the efforts of all the subsequent seven SCTP
+ interoperability tests and those who commented on RFC 4460 as shown
+ in its acknowledgements:
+
+ Barry Zuckerman, La Monte Yarroll, Qiaobing Xie, Wang Xiaopeng,
+ Jonathan Wood, Jeff Waskow, Mike Turner, John Townsend, Sabina
+ Torrente, Cliff Thomas, Yuji Suzuki, Manoj Solanki, Sverre Slotte,
+ Keyur Shah, Jan Rovins, Ben Robinson, Renee Revis, Ian Periam, RC
+ Monee, Sanjay Rao, Sujith Radhakrishnan, Heinz Prantner, Biren Patel,
+ Nathalie Mouellic, Mitch Miers, Bernward Meyknecht, Stan McClellan,
+ Oliver Mayor, Tomas Orti Martin, Sandeep Mahajan, David Lehmann,
+ Jonathan Lee, Philippe Langlois, Karl Knutson, Joe Keller, Gareth
+ Keily, Andreas Jungmaier, Janardhan Iyengar, Mutsuya Irie, John
+ Hebert, Kausar Hassan, Fred Hasle, Dan Harrison, Jon Grim, Laurent
+ Glaude, Steven Furniss, Atsushi Fukumoto, Ken Fujita, Steve Dimig,
+
+
+
+Stewart Standards Track [Page 137]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Thomas Curran, Serkan Cil, Melissa Campbell, Peter Butler, Rob
+ Brennan, Harsh Bhondwe, Brian Bidulock, Caitlin Bestler, Jon Berger,
+ Robby Benedyk, Stephen Baucke, Sandeep Balani, and Ronnie Sellar.
+
+ A special thanks to Mark Allman, who should actually be a co-author
+ for his work on the max-burst, but managed to wiggle out due to a
+ technicality. Also, we would like to acknowledge Lyndon Ong and Phil
+ Conrad for their valuable input and many contributions.
+
+ And finally, you have this document, and those who have commented
+ upon that including Alfred Hoenes and Ronnie Sellars.
+
+ My thanks cannot be adequately expressed to all of you who have
+ participated in the coding, testing, and updating process of this
+ document. All I can say is, Thank You!
+
+ Randall Stewart - Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 138]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+Appendix A. Explicit Congestion Notification
+
+ ECN [RFC3168] describes a proposed extension to IP that details a
+ method to become aware of congestion outside of datagram loss. This
+ is an optional feature that an implementation MAY choose to add to
+ SCTP. This appendix details the minor differences implementers will
+ need to be aware of if they choose to implement this feature. In
+ general, [RFC3168] should be followed with the following exceptions.
+
+ Negotiation:
+
+ [RFC3168] details negotiation of ECN during the SYN and SYN-ACK
+ stages of a TCP connection. The sender of the SYN sets 2 bits in the
+ TCP flags, and the sender of the SYN-ACK sets only 1 bit. The
+ reasoning behind this is to ensure that both sides are truly ECN
+ capable. For SCTP, this is not necessary. To indicate that an
+ endpoint is ECN capable, an endpoint SHOULD add to the INIT and or
+ INIT ACK chunk the TLV reserved for ECN. This TLV contains no
+ parameters, and thus has the following format:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 32768 | Parameter Length = 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ECN-Echo:
+
+ [RFC3168] details a specific bit for a receiver to send back in its
+ TCP acknowledgements to notify the sender of the Congestion
+ Experienced (CE) bit having arrived from the network. For SCTP, this
+ same indication is made by including the ECNE chunk. This chunk
+ contains one data element, i.e., the lowest TSN associated with the
+ IP datagram marked with the CE bit, and looks as follows:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type=12 | Flags=00000000| Chunk Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Lowest TSN Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: The ECNE is considered a Control chunk.
+
+
+
+
+
+
+
+Stewart Standards Track [Page 139]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ CWR:
+
+ [RFC3168] details a specific bit for a sender to send in the header
+ of its next outbound TCP segment to indicate to its peer that it has
+ reduced its congestion window. This is termed the CWR bit. For
+ SCTP, the same indication is made by including the CWR chunk. This
+ chunk contains one data element, i.e., the TSN number that was sent
+ in the ECNE chunk. This element represents the lowest TSN number in
+ the datagram that was originally marked with the CE bit.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Chunk Type=13 | Flags=00000000| Chunk Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Lowest TSN Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Note: The CWR is considered a Control chunk.
+
+Appendix B. CRC32c Checksum Calculation
+
+ We define a 'reflected value' as one that is the opposite of the
+ normal bit order of the machine. The 32-bit CRC (Cyclic Redundancy
+ Check) is calculated as described for CRC32c and uses the polynomial
+ code 0x11EDC6F41 (Castagnoli93) or x^32+x^28+x^27+x^26+x^25
+ +x^23+x^22+x^20+x^19+x^18+ x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0. The
+ CRC is computed using a procedure similar to ETHERNET CRC [ITU32],
+ modified to reflect transport-level usage.
+
+ CRC computation uses polynomial division. A message bit-string M is
+ transformed to a polynomial, M(X), and the CRC is calculated from
+ M(X) using polynomial arithmetic.
+
+ When CRCs are used at the link layer, the polynomial is derived from
+ on-the-wire bit ordering: the first bit 'on the wire' is the high-
+ order coefficient. Since SCTP is a transport-level protocol, it
+ cannot know the actual serial-media bit ordering. Moreover,
+ different links in the path between SCTP endpoints may use different
+ link-level bit orders.
+
+ A convention must therefore be established for mapping SCTP transport
+ messages to polynomials for purposes of CRC computation. The bit-
+ ordering for mapping SCTP messages to polynomials is that bytes are
+ taken most-significant first, but within each byte, bits are taken
+ least-significant first. The first byte of the message provides the
+ eight highest coefficients. Within each byte, the least-significant
+ SCTP bit gives the most-significant polynomial coefficient within
+
+
+
+Stewart Standards Track [Page 140]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ that byte, and the most-significant SCTP bit is the least-significant
+ polynomial coefficient in that byte. (This bit ordering is sometimes
+ called 'mirrored' or 'reflected' [WILLIAMS93].) CRC polynomials are
+ to be transformed back into SCTP transport-level byte values, using a
+ consistent mapping.
+
+ The SCTP transport-level CRC value should be calculated as follows:
+
+ - CRC input data are assigned to a byte stream, numbered from 0 to
+ N-1.
+
+ - The transport-level byte stream is mapped to a polynomial value.
+ An N-byte PDU with j bytes numbered 0 to N-1 is considered as
+ coefficients of a polynomial M(x) of order 8N-1, with bit 0 of
+ byte j being coefficient x^(8(N-j)-8), and bit 7 of byte j being
+ coefficient x^(8(N-j)-1).
+
+ - The CRC remainder register is initialized with all 1s and the CRC
+ is computed with an algorithm that simultaneously multiplies by
+ x^32 and divides by the CRC polynomial.
+
+ - The polynomial is multiplied by x^32 and divided by G(x), the
+ generator polynomial, producing a remainder R(x) of degree less
+ than or equal to 31.
+
+ - The coefficients of R(x) are considered a 32-bit sequence.
+
+ - The bit sequence is complemented. The result is the CRC
+ polynomial.
+
+ - The CRC polynomial is mapped back into SCTP transport-level bytes.
+ The coefficient of x^31 gives the value of bit 7 of SCTP byte 0,
+ and the coefficient of x^24 gives the value of bit 0 of byte 0.
+ The coefficient of x^7 gives bit 7 of byte 3, and the coefficient
+ of x^0 gives bit 0 of byte 3. The resulting 4-byte transport-
+ level sequence is the 32-bit SCTP checksum value.
+
+ IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+ literature on CRCs often follow an alternative formulation, in which
+ the register used to hold the remainder of the long-division
+ algorithm is initialized to zero rather than all-1s, and instead the
+ first 32 bits of the message are complemented. The long-division
+ algorithm used in our formulation is specified such that the initial
+ multiplication by 2^32 and the long-division are combined into one
+ simultaneous operation. For such algorithms, and for messages longer
+ than 64 bits, the two specifications are precisely equivalent. That
+ equivalence is the intent of this document.
+
+
+
+
+Stewart Standards Track [Page 141]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ Implementors of SCTP are warned that both specifications are to be
+ found in the literature, sometimes with no restriction on the long-
+ division algorithm. The choice of formulation in this document is to
+ permit non-SCTP usage, where the same CRC algorithm may be used to
+ protect messages shorter than 64 bits.
+
+ There may be a computational advantage in validating the association
+ against the Verification Tag, prior to performing a checksum, as
+ invalid tags will result in the same action as a bad checksum in most
+ cases. The exceptions for this technique would be INIT and some
+ SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE ECHO. These
+ special-case exchanges must represent small packets and will minimize
+ the effect of the checksum calculation.
+
+Appendix C. ICMP Handling
+
+ Whenever an ICMP message is received by an SCTP endpoint, the
+ following procedures MUST be followed to ensure proper utilization of
+ the information being provided by layer 3.
+
+ ICMP1) An implementation MAY ignore all ICMPv4 messages where the
+ type field is not set to "Destination Unreachable".
+
+ ICMP2) An implementation MAY ignore all ICMPv6 messages where the
+ type field is not "Destination Unreachable", "Parameter
+ Problem",, or "Packet Too Big".
+
+ ICMP3) An implementation MAY ignore any ICMPv4 messages where the
+ code does not indicate "Protocol Unreachable" or
+ "Fragmentation Needed".
+
+ ICMP4) An implementation MAY ignore all ICMPv6 messages of type
+ "Parameter Problem" if the code is not "Unrecognized Next
+ Header Type Encountered".
+
+ ICMP5) An implementation MUST use the payload of the ICMP message (v4
+ or v6) to locate the association that sent the message to
+ which ICMP is responding. If the association cannot be found,
+ an implementation SHOULD ignore the ICMP message.
+
+ ICMP6) An implementation MUST validate that the Verification Tag
+ contained in the ICMP message matches the Verification Tag of
+ the peer. If the Verification Tag is not 0 and does NOT
+ match, discard the ICMP message. If it is 0 and the ICMP
+ message contains enough bytes to verify that the chunk type is
+ an INIT chunk and that the Initiate Tag matches the tag of the
+
+
+
+
+
+Stewart Standards Track [Page 142]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ peer, continue with ICMP7. If the ICMP message is too short
+ or the chunk type or the Initiate Tag does not match, silently
+ discard the packet.
+
+ ICMP7) If the ICMP message is either a v6 "Packet Too Big" or a v4
+ "Fragmentation Needed", an implementation MAY process this
+ information as defined for PATH MTU discovery.
+
+ ICMP8) If the ICMP code is an "Unrecognized Next Header Type
+ Encountered" or a "Protocol Unreachable", an implementation
+ MUST treat this message as an abort with the T bit set if it
+ does not contain an INIT chunk. If it does contain an INIT
+ chunk and the association is in the COOKIE-WAIT state, handle
+ the ICMP message like an ABORT.
+
+ ICMP9) If the ICMPv6 code is "Destination Unreachable", the
+ implementation MAY mark the destination into the unreachable
+ state or alternatively increment the path error counter.
+
+ Note that these procedures differ from [RFC1122] and from its
+ requirements for processing of port-unreachable messages and the
+ requirements that an implementation MUST abort associations in
+ response to a "protocol unreachable" message. Port-unreachable
+ messages are not processed, since an implementation will send an
+ ABORT, not a port unreachable. The stricter handling of the
+ "protocol unreachable" message is due to security concerns for hosts
+ that do NOT support SCTP.
+
+ The following non-normative sample code is taken from an open-source
+ CRC generator [WILLIAMS93], using the "mirroring" technique and
+ yielding a lookup table for SCTP CRC32c with 256 entries, each 32
+ bits wide. While neither especially slow nor especially fast, as
+ software table-lookup CRCs go, it has the advantage of working on
+ both big-endian and little-endian CPUs, using the same (host-order)
+ lookup tables, and using only the predefined ntohl() and htonl()
+ operations. The code is somewhat modified from [WILLIAMS93], to
+ ensure portability between big-endian and little-endian
+ architectures. (Note that if the byte endian-ness of the target
+ architecture is known to be little-endian, the final bit-reversal and
+ byte-reversal steps can be folded into a single operation.)
+
+ /*************************************************************/
+ /* Note Definition for Ross Williams table generator would */
+ /* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE */
+ /* For Mr. Williams direct calculation code use the settings */
+ /* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF, */
+ /* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000 */
+ /*************************************************************/
+
+
+
+Stewart Standards Track [Page 143]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ /* Example of the crc table file */
+ #ifndef __crc32cr_table_h__
+ #define __crc32cr_table_h__
+
+ #define CRC32C_POLY 0x1EDC6F41
+ #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
+
+ unsigned long crc_c[256] =
+ {
+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+ 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+ 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+ 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+ 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+ 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+ 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+ 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+ 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+ 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+ 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+
+ 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+ 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+ 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+ 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+ 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+ 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+ 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+ 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+ 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+ 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+ 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+ 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+ 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+ 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+ 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+ 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+ 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+ 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+ 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+ 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+
+
+
+Stewart Standards Track [Page 144]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+ 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+ 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+ 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+ 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+ 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+ 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+ 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+ 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+ 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+ 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+ 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+ 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+ 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+ 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+ 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+ 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+ 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+
+ 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+ 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+ 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+ };
+
+ #endif
+
+ /* Example of table build routine */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ #define OUTPUT_FILE "crc32cr.h"
+ #define CRC32C_POLY 0x1EDC6F41L
+ FILE *tf;
+ unsigned long
+ reflect_32 (unsigned long b)
+ {
+ int i;
+ unsigned long rw = 0L;
+
+ for (i = 0; i < 32; i++){
+ if (b & 1)
+ rw |= 1 << (31 - i);
+
+
+
+Stewart Standards Track [Page 145]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ b >>= 1;
+ }
+ return (rw);
+ }
+
+ unsigned long
+ build_crc_table (int index)
+ {
+ int i;
+ unsigned long rb;
+
+ rb = reflect_32 (index);
+
+ for (i = 0; i < 8; i++){
+ if (rb & 0x80000000L)
+ rb = (rb << 1) ^ CRC32C_POLY;
+ else
+ rb <<= 1;
+ }
+ return (reflect_32 (rb));
+ }
+
+ main ()
+ {
+ int i;
+
+ printf ("\nGenerating CRC-32c table file <%s>\n",
+ OUTPUT_FILE);
+ if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
+ printf ("Unable to open %s\n", OUTPUT_FILE);
+ exit (1);
+ }
+ fprintf (tf, "#ifndef __crc32cr_table_h__\n");
+ fprintf (tf, "#define __crc32cr_table_h__\n\n");
+ fprintf (tf, "#define CRC32C_POLY 0x%08lX\n",
+ CRC32C_POLY);
+ fprintf (tf,
+ "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
+ fprintf (tf, "\nunsigned long crc_c[256] =\n{\n");
+ for (i = 0; i < 256; i++){
+ fprintf (tf, "0x%08lXL, ", build_crc_table (i));
+ if ((i & 3) == 3)
+ fprintf (tf, "\n");
+ }
+ fprintf (tf, "};\n\n#endif\n");
+
+ if (fclose (tf) != 0)
+ printf ("Unable to close <%s>." OUTPUT_FILE);
+
+
+
+Stewart Standards Track [Page 146]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ else
+ printf ("\nThe CRC-32c table has been written to <%s>.\n",
+ OUTPUT_FILE);
+ }
+
+ /* Example of crc insertion */
+
+ #include "crc32cr.h"
+
+ unsigned long
+ generate_crc32c(unsigned char *buffer, unsigned int length)
+ {
+ unsigned int i;
+ unsigned long crc32 = ~0L;
+ unsigned long result;
+ unsigned char byte0,byte1,byte2,byte3;
+
+ for (i = 0; i < length; i++){
+ CRC32C(crc32, buffer[i]);
+ }
+
+ result = ~crc32;
+
+ /* result now holds the negated polynomial remainder;
+ * since the table and algorithm is "reflected" [williams95].
+ * That is, result has the same value as if we mapped the message
+ * to a polynomial, computed the host-bit-order polynomial
+ * remainder, performed final negation, then did an end-for-end
+ * bit-reversal.
+ * Note that a 32-bit bit-reversal is identical to four inplace
+ * 8-bit reversals followed by an end-for-end byteswap.
+ * In other words, the bytes of each bit are in the right order,
+ * but the bytes have been byteswapped. So we now do an explicit
+ * byteswap. On a little-endian machine, this byteswap and
+ * the final ntohl cancel out and could be elided.
+ */
+
+ byte0 = result & 0xff;
+ byte1 = (result>>8) & 0xff;
+ byte2 = (result>>16) & 0xff;
+ byte3 = (result>>24) & 0xff;
+ crc32 = ((byte0 << 24) |
+ (byte1 << 16) |
+ (byte2 << 8) |
+ byte3);
+ return ( crc32 );
+ }
+
+
+
+
+Stewart Standards Track [Page 147]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ int
+ insert_crc32(unsigned char *buffer, unsigned int length)
+ {
+ SCTP_message *message;
+ unsigned long crc32;
+ message = (SCTP_message *) buffer;
+ message->common_header.checksum = 0L;
+ crc32 = generate_crc32c(buffer,length);
+ /* and insert it into the message */
+ message->common_header.checksum = htonl(crc32);
+ return 1;
+ }
+
+ int
+ validate_crc32(unsigned char *buffer, unsigned int length)
+ {
+ SCTP_message *message;
+ unsigned int i;
+ unsigned long original_crc32;
+ unsigned long crc32 = ~0L;
+
+ /* save and zero checksum */
+ message = (SCTP_message *) buffer;
+ original_crc32 = ntohl(message->common_header.checksum);
+ message->common_header.checksum = 0L;
+ crc32 = generate_crc32c(buffer,length);
+ return ((original_crc32 == crc32)? 1 : -1);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 148]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+References
+
+Normative References
+
+ [ITU32] "ITU-T Recommendation V.42, "Error-correcting procedures
+ for DCEs using asynchronous-to-synchronous
+ conversion".", ITU-T section 8.1.1.6.2.
+
+ [RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+ August 1980.
+
+ [RFC0793] Postel, J., "Transmission Control Protocol", STD 7, RFC
+ 793, September 1981.
+
+ [RFC1122] Braden, R., Ed., "Requirements for Internet Hosts -
+ Communication Layers", STD 3, RFC 1122, October 1989.
+
+ [RFC1123] Braden, R., Ed., "Requirements for Internet Hosts -
+ Application and Support", STD 3, RFC 1123, October 1989.
+
+ [RFC1191] Mogul, J. and S. Deering, "Path MTU discovery", RFC
+ 1191, November 1990.
+
+ [RFC1981] McCann, J., Deering, S., and J. Mogul, "Path MTU
+ Discovery for IP version 6", RFC 1981, August 1996.
+
+ [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC
+ 1982, August 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
+ IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6
+ (IPv6) Specification", RFC 2460, December 1998.
+
+ [RFC2581] Allman, M., Paxson, V., and W. Stevens, "TCP Congestion
+ Control", RFC 2581, April 1999.
+
+ [RFC3873] Pastor, J. and M. Belinchon, "Stream Control
+ Transmission Protocol (SCTP) Management Information Base
+ (MIB)", RFC 3873, September 2004.
+
+ [RFC4291] Hinden, R. and S. Deering, "IP Version 6 Addressing
+ Architecture", RFC 4291, February 2006.
+
+
+
+Stewart Standards Track [Page 149]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ [RFC4301] Kent, S. and K. Seo, "Security Architecture for the
+ Internet Protocol", RFC 4301, December 2005.
+
+ [RFC4303] Kent, S., "IP Encapsulating Security Payload (ESP)", RFC
+ 4303, December 2005.
+
+ [RFC4306] Kaufman, C., Ed., "Internet Key Exchange (IKEv2)
+ Protocol", RFC 4306, December 2005.
+
+ [RFC4821] Mathis, M. and J. Heffner, "Packetization Layer Path MTU
+ Discovery", RFC 4821, March 2007.
+
+Informative References
+
+ [FALL96] Fall, K. and S. Floyd, "Simulation-based Comparisons of
+ Tahoe, Reno, and SACK TCP", SIGCOMM'99 V. 26 N. 3 pp 5-
+ 21, July 1996.
+
+ [SAVAGE99] Savage, S., Cardwell, N., Wetherall, D., and T.
+ Anderson, "TCP Congestion Control with a Misbehaving
+ Receiver", ACM Computer Communications Review 29(5),
+ October 1999.
+
+ [ALLMAN99] Allman, M. and V. Paxson, "On Estimating End-to-End
+ Network Path Properties", SIGCOMM'99 , 1999.
+
+ [WILLIAMS93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR DETECTION
+ ALGORITHMS", Internet publication,
+ http://www.geocities.com/SiliconValley/Pines/
+ 8659/crc.htm, August 1993.
+
+ [RFC0813] Clark, D., "Window and Acknowledgement Strategy in TCP",
+ RFC 813, July 1982.
+
+ [RFC1858] Ziemba, G., Reed, D., and P. Traina, "Security
+ Considerations for IP Fragment Filtering", RFC 1858,
+ October 1995.
+
+ [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC:
+ Keyed-Hashing for Message Authentication", RFC 2104,
+ February 1997.
+
+ [RFC2196] Fraser, B., "Site Security Handbook", FYI 8, RFC 2196,
+ September 1997.
+
+ [RFC2522] Karn, P. and W. Simpson, "Photuris: Session-Key
+ Management Protocol", RFC 2522, March 1999.
+
+
+
+
+Stewart Standards Track [Page 150]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L., and V. Paxson, "Stream Control Transmission
+ Protocol", RFC 2960, October 2000.
+
+ [RFC3309] Stone, J., Stewart, R., and D. Otis, "Stream Control
+ Transmission Protocol (SCTP) Checksum Change", RFC 3309,
+ September 2002.
+
+ [RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition
+ of Explicit Congestion Notification (ECN) to IP", RFC
+ 3168, September 2001.
+
+ [RFC4086] Eastlake, D., 3rd, Schiller, J., and S. Crocker,
+ "Randomness Requirements for Security", BCP 106, RFC
+ 4086, June 2005.
+
+ [RFC4460] Stewart, R., Arias-Rodriguez, I., Poon, K., Caro, A.,
+ and M. Tuexen, "Stream Control Transmission Protocol
+ (SCTP) Specification Errata and Issues", RFC 4460, April
+ 2006.
+
+ [RFC4895] Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+ "Authenticated Chunks for Stream Control Transmission
+ Protocol (SCTP)", RFC 4895, August 2007.
+
+Editor's Address
+
+ Randall R. Stewart
+ 4875 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ US
+
+ EMail: rrs@cisco.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 151]
+
+RFC 4960 Stream Control Transmission Protocol September 2007
+
+
+Full Copyright Statement
+
+ Copyright (C) The IETF Trust (2007).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+ THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart Standards Track [Page 152]
+
diff --git a/doc/rfc5061.txt b/doc/rfc5061.txt
new file mode 100644
index 0000000..3738e5a
--- /dev/null
+++ b/doc/rfc5061.txt
@@ -0,0 +1,2299 @@
+
+
+
+
+
+
+Network Working Group R. Stewart
+Request for Comments: 5061 Cisco Systems, Inc.
+Category: Standards Track Q. Xie
+ Motorola, Inc.
+ M. Tuexen
+ Univ. of Applied Sciences Muenster
+ S. Maruyama
+ M. Kozuka
+ Kyoto University
+ September 2007
+
+
+ Stream Control Transmission Protocol (SCTP)
+ Dynamic Address Reconfiguration
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ A local host may have multiple points of attachment to the Internet,
+ giving it a degree of fault tolerance from hardware failures. Stream
+ Control Transmission Protocol (SCTP) (RFC 4960) was developed to take
+ full advantage of such a multi-homed host to provide a fast failover
+ and association survivability in the face of such hardware failures.
+ This document describes an extension to SCTP that will allow an SCTP
+ stack to dynamically add an IP address to an SCTP association,
+ dynamically delete an IP address from an SCTP association, and to
+ request to set the primary address the peer will use when sending to
+ an endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 1]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 3. Serial Number Arithmetic . . . . . . . . . . . . . . . . . . . 4
+ 4. Additional Chunks and Parameters . . . . . . . . . . . . . . . 4
+ 4.1. New Chunk Types . . . . . . . . . . . . . . . . . . . . . 4
+ 4.1.1. Address Configuration Change Chunk (ASCONF) . . . . . 5
+ 4.1.2. Address Configuration Acknowledgment Chunk
+ (ASCONF-ACK) . . . . . . . . . . . . . . . . . . . . . 6
+ 4.2. New Parameter Types . . . . . . . . . . . . . . . . . . . 7
+ 4.2.1. Add IP Address . . . . . . . . . . . . . . . . . . . . 8
+ 4.2.2. Delete IP Address . . . . . . . . . . . . . . . . . . 9
+ 4.2.3. Error Cause Indication . . . . . . . . . . . . . . . . 10
+ 4.2.4. Set Primary IP Address . . . . . . . . . . . . . . . . 11
+ 4.2.5. Success Indication . . . . . . . . . . . . . . . . . . 12
+ 4.2.6. Adaptation Layer Indication . . . . . . . . . . . . . 13
+ 4.2.7. Supported Extensions Parameter . . . . . . . . . . . . 13
+ 4.3. New Error Causes . . . . . . . . . . . . . . . . . . . . . 14
+ 4.3.1. Error Cause: Request to Delete Last Remaining IP
+ Address . . . . . . . . . . . . . . . . . . . . . . . 15
+ 4.3.2. Error Cause: Operation Refused Due to Resource
+ Shortage . . . . . . . . . . . . . . . . . . . . . . . 15
+ 4.3.3. Error Cause: Request to Delete Source IP Address . . . 16
+ 4.3.4. Error Cause: Association Aborted Due to Illegal
+ ASCONF-ACK . . . . . . . . . . . . . . . . . . . . . . 17
+ 4.3.5. Error Cause: Request Refused - No Authorization. . . . 17
+ 5. Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 18
+ 5.1. ASCONF Chunk Procedures . . . . . . . . . . . . . . . . . 18
+ 5.1.1. Congestion Control of ASCONF Chunks . . . . . . . . . 20
+ 5.2. Upon Reception of an ASCONF Chunk . . . . . . . . . . . . 21
+ 5.3. General Rules for Address Manipulation . . . . . . . . . . 24
+ 5.3.1. A Special Case for OOTB ABORT Chunks . . . . . . . . . 29
+ 5.3.2. A Special Case for Changing an Address . . . . . . . . 29
+ 5.4. Setting of the Primary Address . . . . . . . . . . . . . . 29
+ 5.5. Bundling of Multiple ASCONFs . . . . . . . . . . . . . . . 30
+ 6. Security Considerations . . . . . . . . . . . . . . . . . . . 30
+ 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33
+ 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 34
+ 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 35
+ 9.1. Normative References . . . . . . . . . . . . . . . . . . . 35
+ 9.2. Informative References . . . . . . . . . . . . . . . . . . 35
+ Appendix A. Abstract Address Handling . . . . . . . . . . . . . . 36
+ A.1. General Remarks . . . . . . . . . . . . . . . . . . . . . 36
+ A.2. Generalized Endpoints . . . . . . . . . . . . . . . . . . 36
+ A.3. Associations . . . . . . . . . . . . . . . . . . . . . . . 37
+ A.4. Relationship with RFC 4960 . . . . . . . . . . . . . . . . 38
+ A.5. Rules for Address Manipulation . . . . . . . . . . . . . . 38
+
+
+
+Stewart, et al. Standards Track [Page 2]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+1. Introduction
+
+ A local host may have multiple points of attachment to the Internet,
+ giving it a degree of fault tolerance from hardware failures. SCTP
+ was developed to take full advantage of such a multi-homed host to
+ provide a fast failover and association survivability in the face of
+ such hardware failures. However, many modern computers allow for the
+ dynamic addition and deletion of network cards (sometimes termed a
+ hot-pluggable interface). Complicate this with the ability of a
+ provider, in IPv6, to dynamically renumber a network, and there still
+ is a gap between full-fault tolerance and the currently defined SCTP
+ protocol. No matter if a card is added or an interface is
+ renumbered, in order to take advantage of this new configuration, the
+ transport association must be restarted. For many fault-tolerant
+ applications this restart is considered an outage and is undesirable.
+
+ This document describes an extension to SCTP to attempt to correct
+ this problem for the more demanding fault-tolerant application. This
+ extension will allow an SCTP stack to:
+
+ o Dynamically add an IP address to an association.
+
+ o Dynamically delete an IP address from an association.
+
+ o Request to set the primary address the peer will use when sending
+ to an endpoint.
+
+ The dynamic addition and subtraction of IP addresses allows an SCTP
+ association to continue to function through host and network
+ reconfigurations. These changes, brought on by provider or user
+ action, may mean that the peer would be better served by using the
+ newly added address; however, this information may only be known by
+ the endpoint that had the reconfiguration occur. In such a case this
+ extension allows the local endpoint to advise the peer as to what it
+ thinks is the better primary address that the peer should be using.
+
+ One last thing this extension adds is a small, 32-bit integer called
+ an adaptation indication that can be exchanged at startup. This is
+ useful for applications where there are one or more specific layers
+ below the application, yet still above SCTP. In such a case, the
+ exchange of this indication can allow the proper layer to be enabled
+ below the application.
+
+2. Conventions
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC2119].
+
+
+
+Stewart, et al. Standards Track [Page 3]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+3. Serial Number Arithmetic
+
+ It is essential to remember that the actual Address Configuration
+ Change Chunk (ASCONF) Sequence Number space is finite, though very
+ large. This space ranges from 0 to 2**32 - 1. Since the space is
+ finite, all arithmetic dealing with ASCONF Sequence Numbers MUST be
+ performed modulo 2**32. This unsigned arithmetic preserves the
+ relationship of sequence numbers as they cycle from 2**32 - 1 to 0
+ again. There are some subtleties to computer modulo arithmetic, so
+ great care should be taken in programming the comparison of such
+ values. When referring to ASCONF Sequence Numbers, the symbol "=<"
+ means "less than or equal"(modulo 2**32).
+
+ Comparisons and arithmetic on ASCONF sequence numbers in this
+ document SHOULD use Serial Number Arithmetic as defined in [RFC1982]
+ where SERIAL_BITS = 32.
+
+ ASCONF Sequence Numbers wrap around when they reach 2**32 - 1. That
+ is, the next ASCONF Sequence Number an ASCONF chunk MUST use after
+ transmitting an ASCONF Sequence Number = 2**32 - 1 is 0.
+
+ Any arithmetic done on Stream Sequence Numbers SHOULD use Serial
+ Number Arithmetic (as defined in [RFC1982]) where SERIAL_BITS = 16.
+ All other arithmetic and comparisons in this document use normal
+ arithmetic.
+
+4. Additional Chunks and Parameters
+
+ This section describes the addition of two new chunks and seven new
+ parameters to allow:
+
+ o Dynamic addition of IP addresses to an association.
+
+ o Dynamic deletion of IP addresses from an association.
+
+ o A request to set the primary address the peer will use when
+ sending to an endpoint.
+
+ Additionally, this section describes three new Error Causes that
+ support these new chunks and parameters.
+
+4.1. New Chunk Types
+
+ This section defines two new chunk types that will be used to
+ transfer the control information reliably. Table 1 illustrates the
+ two new chunk types.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 4]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Chunk Type Chunk Name
+ --------------------------------------------------------------
+ 0xC1 Address Configuration Change Chunk (ASCONF)
+ 0x80 Address Configuration Acknowledgment (ASCONF-ACK)
+
+ Table 1: Address Configuration Chunks
+
+4.1.1. Address Configuration Change Chunk (ASCONF)
+
+ This chunk is used to communicate to the remote endpoint one of the
+ configuration change requests that MUST be acknowledged. The
+ information carried in the ASCONF Chunk uses the form of a Type-
+ Length-Value (TLV), as described in "3.2.1 Optional/Variable-length
+ Parameter Format" in [RFC4960] for all variable parameters. This
+ chunk MUST be sent in an authenticated way by using the mechanism
+ defined in [RFC4895]. If this chunk is received unauthenticated it
+ MUST be silently discarded as described in [RFC4895].
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0xC1 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Parameter |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF Parameter #1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / .... /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF Parameter #N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Sequence Number: 32 bits (unsigned integer)
+
+ This value represents a Sequence Number for the ASCONF Chunk. The
+ valid range of a Sequence Number is from 0 to 4294967295 (2**32 - 1).
+ Sequence Numbers wrap back to 0 after reaching 4294967295.
+
+ Address Parameter: 8 or 20 bytes (depending on the address type)
+
+ This field contains an address parameter, either IPv6 or IPv4, from
+ [RFC4960]. The address is an address of the sender of the ASCONF
+ Chunk; the address MUST be considered part of the association by the
+ peer endpoint (the receiver of the ASCONF Chunk). This field may be
+
+
+
+Stewart, et al. Standards Track [Page 5]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ used by the receiver of the ASCONF to help in finding the
+ association. If the address 0.0.0.0 or ::0 is provided, the receiver
+ MAY lookup the association by other information provided in the
+ packet. This parameter MUST be present in every ASCONF message, i.e.
+ it is a mandatory TLV parameter.
+
+ Note: The host name address MUST NOT be sent and MUST be ignored if
+ received in any ASCONF message.
+
+ It should be noted that the ASCONF Chunk format requires the receiver
+ to report to the sender if it does not understand the ASCONF Chunk.
+ This is accomplished by setting the upper bits in the chunk type as
+ described in [RFC4960], Section 3.2. Note that the upper two bits in
+ the ASCONF Chunk are set to one. As defined in [RFC4960], Section
+ 3.2, when setting these upper bits in this manner the receiver that
+ does not understand this chunk MUST skip the chunk and continue
+ processing, and report in an Operation Error Chunk using the
+ 'Unrecognized Chunk Type' cause of error. This will NOT abort the
+ association but indicates to the sender that it MUST not send any
+ further ASCONF chunks.
+
+ ASCONF Parameter: TLV format
+
+ Each address configuration change is represented by a TLV parameter,
+ as defined in Section 4.2. One or more requests may be present in an
+ ASCONF Chunk.
+
+4.1.2. Address Configuration Acknowledgment Chunk (ASCONF-ACK)
+
+ This chunk is used by the receiver of an ASCONF Chunk to acknowledge
+ the reception. It carries zero or more results for any ASCONF
+ parameters that were processed by the receiver. This chunk MUST be
+ sent in an authenticated way by using the mechanism defined in
+ [RFC4895]. If this chunk is received unauthenticated it MUST be
+ silently discarded as described in [RFC4895].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 6]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0x80 | Chunk Flags | Chunk Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Sequence Number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF Parameter Response#1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ \
+ / .... /
+ \ \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF Parameter Response#N |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Sequence Number: 32 bits (unsigned integer)
+
+ This value represents the Sequence Number for the received ASCONF
+ Chunk that is acknowledged by this chunk. This value is copied from
+ the received ASCONF Chunk.
+
+ ASCONF Parameter Response: TLV format
+
+ The ASCONF Parameter Response is used in the ASCONF-ACK to report the
+ status of ASCONF processing. By default, if a responding endpoint
+ does not include any Error Cause, a success is indicated. Thus a
+ sender of an ASCONF-ACK MAY indicate complete success of all TLVs in
+ an ASCONF by returning only the Chunk Type, Chunk Flags, Chunk Length
+ (set to 8), and the Sequence Number.
+
+4.2. New Parameter Types
+
+ The seven new parameters added follow the format defined in Section
+ 3.2.1 of [RFC4960]. Tables 2, 3, and 4 describe the parameters.
+
+ Address Configuration Parameters Parameter Type
+ -------------------------------------------------
+ Set Primary Address 0xC004
+ Adaptation Layer Indication 0xC006
+ Supported Extensions 0x8008
+
+ Table 2: Parameters That Can Be Used in an INIT/INIT-ACK Chunk
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 7]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Address Configuration Parameters Parameter Type
+ -------------------------------------------------
+ Add IP Address 0xC001
+ Delete IP Address 0xC002
+ Set Primary Address 0xC004
+
+ Table 3: Parameters Used in an ASCONF Parameter
+
+
+ Address Configuration Parameters Parameter Type
+ -------------------------------------------------
+ Error Cause Indication 0xC003
+ Success Indication 0xC005
+
+ Table 4: Parameters Used in an ASCONF Parameter Response
+
+ Any parameter that appears where it is not allowed (for example, a
+ 0xC002 parameter appearing within an INIT or INIT-ACK) MAY be
+ responded to with an ABORT by the receiver of the invalid parameter.
+ If the receiver chooses NOT to abort, the parameter MUST be ignored.
+ A robust implementation SHOULD ignore the parameter and leave the
+ association intact.
+
+4.2.1. Add IP Address
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0xC001 | Length = Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF-Request Correlation ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Parameter |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ASCONF-Request Correlation ID: 32 bits
+
+ This is an opaque integer assigned by the sender to identify each
+ request parameter. The receiver of the ASCONF Chunk will copy this
+ 2-bit value into the ASCONF Response Correlation ID field of the
+ ASCONF-ACK response parameter. The sender of the ASCONF can use this
+ same value in the ASCONF-ACK to find which request the response is
+ for. Note that the receiver MUST NOT change this 32-bit value.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 8]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Address Parameter: TLV
+
+ This field contains an IPv4 or IPv6 address parameter as described in
+ Section 3.3.2.1 of [RFC4960]. The complete TLV is wrapped within
+ this parameter. It informs the receiver that the address specified
+ is to be added to the existing association. This parameter MUST NOT
+ contain a broadcast or multicast address. If the address 0.0.0.0 or
+ ::0 is provided, the source address of the packet MUST be added.
+
+ An example TLV requesting that the IPv4 address 192.0.2.1 be added to
+ the association would look as follows:
+
+ +--------------------------------+
+ | Type=0xC001 | Length = 16 |
+ +--------------------------------+
+ | C-ID = 0x01023474 |
+ +--------------------------------+
+ | Type=5 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+ Valid Chunk Appearance
+
+ The Add IP Address parameter may only appear in the ASCONF Chunk
+ type.
+
+4.2.2. Delete IP Address
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type =0xC002 | Length = Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF-Request Correlation ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Parameter |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ASCONF-Request Correlation ID: 32 bits
+
+ This is an opaque integer assigned by the sender to identify each
+ request parameter. The receiver of the ASCONF Chunk will copy this
+ 32-bit value into the ASCONF Response Correlation ID field of the
+ ASCONF-ACK response parameter. The sender of the ASCONF can use this
+ same value in the ASCONF-ACK to find which request the response is
+ for. Note that the receiver MUST NOT change this 32-bit value.
+
+
+
+
+Stewart, et al. Standards Track [Page 9]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Address Parameter: TLV
+
+ This field contains an IPv4 or IPv6 address parameter, as described
+ in Section 3.3.2.1 of [RFC4960]. The complete TLV is wrapped within
+ this parameter. It informs the receiver that the address specified
+ is to be removed from the existing association. This parameter MUST
+ NOT contain a broadcast or multicast address. If the address 0.0.0.0
+ or ::0 is provided, all addresses of the peer except the source
+ address of the packet MUST be deleted.
+
+ An example TLV deleting the IPv4 address 192.0.2.1 from an existing
+ association would look as follows:
+
+ +--------------------------------+
+ | Type=0xC002 | Length = 16 |
+ +--------------------------------+
+ | C-ID = 0x01023476 |
+ +--------------------------------+
+ | Type=5 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+ Valid Chunk Appearance
+
+ The Delete IP Address parameter may only appear in the ASCONF Chunk
+ type.
+
+4.2.3. Error Cause Indication
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0xC003 | Length = Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF-Response Correlation ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Error Cause(s) or Success Indication |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ASCONF-Response Correlation ID: 32 bits
+
+ This is an opaque integer assigned by the sender to identify each
+ request parameter. The receiver of the ASCONF Chunk will copy this
+ 32-bit value from the ASCONF-Request Correlation ID into the ASCONF
+ Response Correlation ID field so the peer can easily correlate the
+ request to this response. Note that the receiver MUST NOT change
+ this 32-bit value.
+
+
+
+Stewart, et al. Standards Track [Page 10]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Error Cause(s): TLV(s)
+
+ When reporting an error, this response parameter is used to wrap one
+ or more standard Error Causes normally found within an SCTP
+ Operational Error or SCTP Abort (as defined in [RFC4960]). The Error
+ Cause(s) follow the format defined in Section 3.3.10 of [RFC4960].
+
+ Valid Chunk Appearance
+
+ The Error Cause Indication parameter may only appear in the ASCONF-
+ ACK Chunk Type.
+
+4.2.4. Set Primary IP Address
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type =0xC004 | Length = Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF-Request Correlation ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Address Parameter |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ ASCONF-Request Correlation ID: 32 bits
+
+ This is an opaque integer assigned by the sender to identify each
+ request parameter. The receiver of the ASCONF Chunk will copy this
+ 32-bit value into the ASCONF Response Correlation ID field of the
+ ASCONF-ACK response parameter. The sender of the ASCONF can use this
+ same value in the ASCONF-ACK to find which request the response is
+ for. Note that the receiver MUST NOT change this 32-bit value.
+
+ Address Parameter: TLV
+
+ This field contains an IPv4 or IPv6 address parameter as described in
+ Section 3.3.2.1 of [RFC4960]. The complete TLV is wrapped within
+ this parameter. It requests the receiver to mark the specified
+ address as the primary address to send data to (see Section 5.1.2 of
+ [RFC4960]). The receiver MAY mark this as its primary address upon
+ receiving this request. If the address 0.0.0.0 or ::0 is provided,
+ the receiver MAY mark the source address of the packet as its
+ primary.
+
+ An example TLV requesting that the IPv4 address 192.0.2.1 be made the
+ primary destination address would look as follows:
+
+
+
+
+
+Stewart, et al. Standards Track [Page 11]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ +--------------------------------+
+ | Type=0xC004 | Length = 16 |
+ +--------------------------------+
+ | C-ID = 0x01023479 |
+ +--------------------------------+
+ | Type=5 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+ Valid Chunk Appearance
+
+ The Set Primary IP Address parameter may appear in the ASCONF, the
+ INIT, or the INIT-ACK Chunk Type. The inclusion of this parameter in
+ the INIT or INIT-ACK can be used to indicate an initial preference of
+ primary address.
+
+4.2.5. Success Indication
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 0xC005 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ASCONF-Response Correlation ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ By default, if a responding endpoint does not report an error for any
+ requested TLV, a success is implicitly indicated. Thus, a sender of
+ an ASCONF-ACK MAY indicate complete success of all TLVs in an ASCONF
+ by returning only the Chunk Type, Chunk Flags, Chunk Length (set to
+ 8), and the Sequence Number.
+
+ The responding endpoint MAY also choose to explicitly report a
+ success for a requested TLV, by returning a success report ASCONF
+ Parameter Response.
+
+ ASCONF-Response Correlation ID: 32 bits
+
+ This is an opaque integer assigned by the sender to identify each
+ request parameter. The receiver of the ASCONF Chunk will copy this
+ 32-bit value from the ASCONF-Request Correlation ID into the ASCONF
+ Response Correlation ID field so the peer can easily correlate the
+ request to this response.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 12]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Valid Chunk Appearance
+
+ The Success Indication parameter may only appear in the ASCONF-ACK
+ Chunk Type.
+
+4.2.6. Adaptation Layer Indication
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type =0xC006 | Length = 8 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Adaptation Code point |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ This parameter is specified for the communication of peer upper-layer
+ protocols. It is envisioned to be used for flow control and other
+ adaptation layers that require an indication to be carried in the
+ INIT and INIT-ACK. Each adaptation layer that is defined that wishes
+ to use this parameter MUST specify an adaptation code point in an
+ appropriate RFC defining its use and meaning. This parameter SHOULD
+ NOT be examined by the receiving SCTP implementation and should be
+ passed opaquely to the upper-layer protocol.
+
+ Note: This parameter is not used in either the addition or deletion
+ of addresses but is for the convenience of the upper layer. This
+ document includes this parameter to minimize the number of SCTP
+ documents.
+
+ Valid Chunk Appearance
+
+ The Adaptation Layer Indication parameter may appear in INIT or INIT-
+ ACK chunk and SHOULD be passed to the receiver's upper-layer protocol
+ based upon the upper-layer protocol configuration of the SCTP stack.
+ This parameter MUST NOT be sent in any other chunks, and if it is
+ received in another chunk, it MUST be ignored.
+
+4.2.7. Supported Extensions Parameter
+
+ This parameter is used at startup to identify any additional
+ extensions that the sender supports. The sender MUST support both
+ the sending and the receiving of any chunk types listed within the
+ Supported Extensions Parameter. An implementation supporting this
+ extension MUST list the ASCONF,the ASCONF-ACK, and the AUTH chunks in
+ its INIT and INIT-ACK parameters.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 13]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Parameter Type = 0x8008 | Parameter Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | CHUNK TYPE 1 | CHUNK TYPE 2 | CHUNK TYPE 3 | CHUNK TYPE 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | .... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | CHUNK TYPE N | PAD | PAD | PAD |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Parameter Type This field holds the IANA-defined parameter type for
+ the Supported Extensions Parameter. The value of this field is
+ 0x8008.
+
+ Parameter Type Length This field holds the length of the parameter,
+ including the Parameter Type, Parameter Length, and any additional
+ supported extensions. Note: The length MUST NOT include any padding.
+
+ CHUNK TYPE X This field(s) hold the chunk type of any SCTP
+ extension(s) that are currently supported by the sending SCTP.
+ Multiple chunk types may be defined listing each additional feature
+ that the sender supports. The sender MUST NOT include multiple
+ Supported Extensions Parameter within any chunk.
+
+ Parameter Appearance This parameter may appear in the INIT or INIT-
+ ACK chunk. This parameter MUST NOT appear in any other chunk.
+
+4.3. New Error Causes
+
+ Five new Error Causes are added to the SCTP Operational Errors,
+ primarily for use in the ASCONF-ACK Chunk.
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 0x00A0 Request to Delete Last Remaining IP Address
+ 0x00A1 Operation Refused Due to Resource Shortage
+ 0x00A2 Request to Delete Source IP Address
+ 0x00A3 Association Aborted Due to Illegal ASCONF-ACK
+ 0x00A4 Request Refused - No Authorization
+
+ Table 5: New Error Causes
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 14]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+4.3.1. Error Cause: Request to Delete Last Remaining IP Address
+
+ Cause of error
+
+ Request to Delete Last Remaining IP Address: The receiver of this
+ error sent a request to delete the last IP address from its
+ association with its peer. This error indicates that the request is
+ rejected.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=0x00A0 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ TLV-Copied-From-ASCONF /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ An example of a failed delete in an Error Cause TLV would look as
+ follows in the response ASCONF-ACK message:
+
+ +--------------------------------+
+ | Type = 0xC003 | Length = 28 |
+ +----------------+---------------+
+ | C-ID = 0x01023476 |
+ +--------------------------------+
+ | Cause=0x00A0 | Length = 20 |
+ +----------------+---------------+
+ | Type= 0xC002 | Length = 16 |
+ +----------------+---------------+
+ | C-ID = 0x01023476 |
+ +--------------------------------+
+ | Type=0x0005 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+4.3.2. Error Cause: Operation Refused Due to Resource Shortage
+
+ Cause of error
+
+ This Error Cause is used to report a failure by the receiver to
+ perform the requested operation due to a lack of resources. The
+ entire TLV that is refused is copied from the ASCONF into the Error
+ Cause.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 15]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=0x00A1 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ TLV-Copied-From-ASCONF /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ An example of a failed addition in an Error Cause TLV would look as
+ follows in the response ASCONF-ACK message:
+
+ +--------------------------------+
+ | Type = 0xC003 | Length = 28 |
+ +--------------------------------+
+ | C-ID = 0x01023474 |
+ +--------------------------------+
+ | Cause=0x00A1 | Length = 20 |
+ +----------------+---------------+
+ | Type=0xC001 | Length = 16 |
+ +--------------------------------+
+ | C-ID = 0x01023474 |
+ +--------------------------------+
+ | Type=0x0005 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+4.3.3. Error Cause: Request to Delete Source IP Address
+
+ Cause of error
+
+ Request to Delete Source IP Address: The receiver of this error sent
+ a request to delete the source IP address of the ASCONF message.
+ This error indicates that the request is rejected.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=0x00A2 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ TLV-Copied-From-ASCONF /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 16]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ An example of a failed delete in an Error Cause TLV would look as
+ follows in the response ASCONF-ACK message:
+
+ +--------------------------------+
+ | Type = 0xC003 | Length = 28 |
+ +--------------------------------+
+ | C-ID = 0x01023476 |
+ +--------------------------------+
+ | Cause=0x00A2 | Length = 20 |
+ +----------------+---------------+
+ | Type=0xC002 | Length = 16 |
+ +----------------+---------------+
+ | C-ID = 0x01023476 |
+ +--------------------------------+
+ | Type=0x0005 | Length = 8 |
+ +----------------+---------------+
+ | Value=0xC0000201 |
+ +----------------+---------------+
+
+ IMPLEMENTATION NOTE: It is unlikely that an endpoint would source a
+ packet from the address being deleted, unless the endpoint does not
+ do proper source address selection.
+
+4.3.4. Error Cause: Association Aborted Due to Illegal ASCONF-ACK
+
+ This error is to be included in an ABORT that is generated due to the
+ reception of an ASCONF-ACK that was not expected but is larger than
+ the current Sequence Number (see Section 5.3, Rule F0 ). Note that a
+ Sequence Number is larger than the last acked Sequence Number if it
+ is either the next sequence or no more than 2**31-1 greater than the
+ current Sequence Number. Sequence Numbers smaller than the last
+ acked Sequence Number are silently ignored.
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=0x00A3 | Cause Length=4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+4.3.5. Error Cause: Request Refused - No Authorization.
+
+ Cause of error
+
+ This Error Cause may be included to reject a request based on local
+ security policies.
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 17]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Cause Code=0x00A4 | Cause Length=Variable |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ \ TLV-Copied-From-ASCONF /
+ / \
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+5. Procedures
+
+ This section will lay out the specific procedures for address-
+ configuration change chunk type and its processing.
+
+5.1. ASCONF Chunk Procedures
+
+ When an endpoint has an ASCONF signaled change to be sent to the
+ remote endpoint, it MUST do the following:
+
+ A1) Create an ASCONF Chunk as defined in Section 4.1.1. The chunk
+ MUST contain all of the TLV(s) of information necessary to be
+ sent to the remote endpoint, and unique correlation identities
+ for each request.
+
+ A2) A Sequence Number MUST be assigned to the Chunk. The Sequence
+ Number MUST be larger by one. The Sequence Number MUST be
+ initialized at the start of the association to the same value as
+ the Initial Transmission Sequence Number (TSN) and every time a
+ new ASCONF Chunk is created, it MUST be incremented by one after
+ assigning the Sequence Number to the newly created chunk.
+
+ A3) If no SCTP packet with one or more ASCONF Chunk(s) is
+ outstanding (unacknowledged) with the remote peer, send the
+ chunk and proceed to step A4. If an ASCONF chunk is
+ outstanding, then the ASCONF chunk should be queued for later
+ transmission and no further action should be taken until the
+ previous ASCONF is acknowledged or a timeout occurs.
+
+ A4) The sender MUST Start a T-4 Retransmission Timeout (RTO) timer,
+ using the RTO value of the selected destination address
+ (normally the primary path; see [RFC4960], Section 6.4 for
+ details).
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 18]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ A5) When the ASCONF-ACK that acknowledges the Sequence Number last
+ sent arrives, the sender MUST stop the T-4 RTO timer, and clear
+ the appropriate association and destination error counters as
+ defined in [RFC4960], Sections 8.1 and 8.2.
+
+ A6) The endpoint MUST process all of the TLVs within the ASCONF-
+ ACK(s) to find out particular status information returned to the
+ various requests that were sent. Use the Correlation IDs to
+ correlate the request and the responses.
+
+ A7) If an error response is received for a TLV parameter, all TLVs
+ with no response before the failed TLV are considered successful
+ if not reported. All TLVs after the failed response are
+ considered unsuccessful unless a specific success indication is
+ present for the parameter.
+
+ A8) If there is no response(s) to specific TLV parameter(s), and no
+ failures are indicated, then all request(s) are considered
+ successful.
+
+ A9) If the peer responds to an ASCONF with an ERROR Chunk reporting
+ that it did not recognize the ASCONF Chunk Type, the sender of
+ the ASCONF MUST NOT send any further ASCONF Chunks and MUST stop
+ its T-4 timer.
+
+ If the T-4 RTO timer expires the endpoint MUST do the following:
+
+ B1) Increment the error counters and perform path failure detection
+ on the appropriate destination address as defined in [RFC4960],
+ Sections 8.1 and 8.2.
+
+ B2) Increment the association error counters and perform endpoint
+ failure detection on the association as defined in [RFC4960],
+ Sections 8.1 and 8.2.
+
+ B3) Backoff the destination address RTO value to which the ASCONF
+ chunk was sent by doubling the RTO timer value.
+
+ Note: The RTO value is used in the setting of all timer types
+ for SCTP. Each destination address has a single RTO estimate.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 19]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ B4) Re-transmit the ASCONF Chunk last sent and if possible choose an
+ alternate destination address (please refer to [RFC4960],
+ Section 6.4.1). An endpoint MUST NOT add new parameters to this
+ chunk; it MUST be the same (including its Sequence Number) as
+ the last ASCONF sent. An endpoint MAY, however, bundle an
+ additional ASCONF with new ASCONF parameters with the next
+ Sequence Number. For details, see Section 5.5.
+
+ B5) Restart the T-4 RTO timer. Note that if a different destination
+ is selected, then the RTO used will be that of the new
+ destination address.
+
+ Note: The total number of retransmissions is limited by B2 above. If
+ the maximum is reached, the association will fail and enter into the
+ CLOSED state (see [RFC4960], Section 6.4.1 for details).
+
+5.1.1. Congestion Control of ASCONF Chunks
+
+ In defining the ASCONF Chunk transfer procedures, it is essential
+ that these transfers MUST NOT cause congestion within the network.
+ To achieve this, we place these restrictions on the transfer of
+ ASCONF Chunks:
+
+ C1) One and only one SCTP packet-holding ASCONF Chunk(s) MAY be in
+ transit and unacknowledged at any one time. If a sender, after
+ sending an ASCONF chunk, decides it needs to transfer another
+ ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk returns
+ from the previous ASCONF Chunk before sending a subsequent
+ ASCONF. Note: This restriction binds each side, so at any time,
+ two ASCONF may be in-transit on any given association (one sent
+ from each endpoint). However, when an ASCONF Chunk is
+ retransmitted due to a time-out, the additionally held ASCONF
+ Chunks can be bundled into the retransmission packet as
+ described in Section 5.5.
+
+ C2) An ASCONF Chunk may be bundled with any other chunk type
+ including other ASCONF Chunks. If bundled with other ASCONF
+ Chunks, the chunks MUST appear in sequential order with respect
+ to their Sequence Number.
+
+ C3) An ASCONF-ACK Chunk may be bundled with any other chunk type
+ including other ASCONF-ACK Chunks. If bundled with other
+ ASCONF-ACK Chunks, the chunks MUST appear in sequential order
+ with respect to their Sequence Number.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 20]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ C4) Both ASCONF and ASCONF-ACK Chunks MUST NOT be sent in any SCTP
+ state except ESTABLISHED, SHUTDOWN-PENDING, SHUTDOWN-RECEIVED,
+ and SHUTDOWN-SENT.
+
+ C5) An ASCONF Chunk and an ASCONF-ACK Chunk SHOULD not be larger
+ than the PMTU. If the PMTU is unknown, then the PMTU should be
+ set to the minimum PMTU. The minimum PMTU depends on the IP
+ version used for transmission, and is the lesser of 576 octets
+ and the first-hop MTU for IPv4 [RFC1122] and 1280 octets for
+ IPv6 [RFC2460].
+
+ An ASCONF sender without these restrictions could possibly flood the
+ network with a large number of separate address-change operations,
+ thus causing network congestion.
+
+ If the sender of an ASCONF Chunk receives an Operational Error
+ indicating that the ASCONF Chunk Type is not understood, then the
+ sender MUST NOT send subsequent ASCONF Chunks to the peer. The
+ endpoint should also inform the upper-layer application that the peer
+ endpoint does not support any of the extensions detailed in this
+ document.
+
+5.2. Upon Reception of an ASCONF Chunk
+
+ When an endpoint receives an ASCONF Chunk from the remote peer,
+ special procedures may be needed to identify the association the
+ ASCONF Chunk is associated with. To properly find the association,
+ the following procedures SHOULD be followed:
+
+ D1) Use the source address and port number of the sender to attempt
+ to identify the association (i.e., use the same method defined
+ in [RFC4960] used for all other SCTP Chunks). If found proceed
+ to rule D4.
+
+ D2) If the association is not found, use the address found in the
+ Address Parameter TLV combined with the port number found in the
+ SCTP common header. If found, proceed to rule D4.
+
+ D2-ext) If more than one ASCONF Chunks are packed together, use the
+ address found in the ASCONF Address Parameter TLV of each of
+ the subsequent ASCONF Chunks. If found, proceed to rule D4.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 21]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ D3) If neither D1, D2, nor D2-ext locates the association, treat the
+ chunk as an Out Of The Blue packet as defined in [RFC4960].
+
+ D4) Follow the normal rules to validate the SCTP verification tag
+ found in [RFC4960].
+
+ D5) After the verification tag has been validated, normal chunk
+ processing should occur. Prior to finding the ASCONF chunk, the
+ receiver MUST encounter an AUTH chunk as described in [RFC4895].
+ If either authentication fails, or the AUTH chunk is missing,
+ the receiver MUST silently discard this chunk and the rest of
+ the packet.
+
+ After identification and verification of the association, the
+ following should be performed to properly process the ASCONF Chunk:
+
+ E1) If the value found in the Sequence Number of the ASCONF Chunk is
+ equal to the ('Peer-Sequence-Number' + 1) and the Sequence
+ Number of the ASCONF Chunk is the first in the SCTP Packet, the
+ endpoint MAY clean any old cached ASCONF-ACK up to the 'Peer-
+ Sequence-Number' and then proceed to rule E4.
+
+ E1-ext) If the value found in the Sequence Number of the ASCONF
+ Chunk is equal to the ('Peer-Sequence-Number' + 1) and the
+ ASCONF chunk is NOT the first Sequence Number in the SCTP
+ packet, proceed to rule E4 but do NOT clear any cached
+ ASCONF- ACK or state information.
+
+ E2) If the value found in the Sequence Number is less than the
+ ('Peer- Sequence-Number' + 1), simply skip to the next ASCONF,
+ and include in the outbound response packet any previously
+ cached ASCONF-ACK response that was sent and saved that matches
+ the Sequence Number of the ASCONF. Note: It is possible that no
+ cached ASCONF-ACK Chunk exists. This will occur when an older
+ ASCONF arrives out of order. In such a case, the receiver
+ should skip the ASCONF Chunk and not include ASCONF-ACK Chunk
+ for that chunk.
+
+ E3) Then, process each ASCONF one by one as above while the Sequence
+ Number of the ASCONF is less than the ('Peer-Sequence-Number' +
+ 1).
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 22]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ E4) When the Sequence Number matches the next one expected, process
+ the ASCONF as described below and after processing the ASCONF
+ Chunk, append an ASCONF-ACK Chunk to the response packet and
+ cache a copy of it (in the event it later needs to be
+ retransmitted).
+
+ V1) Process the TLVs contained within the Chunk performing the
+ appropriate actions as indicated by each TLV type. The
+ TLVs MUST be processed in order within the Chunk. For
+ example, if the sender puts 3 TLVs in one chunk, the first
+ TLV (the one closest to the Chunk Header) in the Chunk MUST
+ be processed first. The next TLV in the chunk (the middle
+ one) MUST be processed second and finally, the last TLV in
+ the Chunk MUST be processed last.
+
+ V2) In processing the chunk, the receiver should build a
+ response message with the appropriate error TLVs, as
+ specified in the Parameter type bits, for any ASCONF
+ Parameter it does not understand. To indicate an
+ unrecognized parameter, Cause Type 8 should be used as
+ defined in the ERROR in Section 3.3.10.8, [RFC4960]. The
+ endpoint may also use the response to carry rejections for
+ other reasons, such as resource shortages, etc., using the
+ Error Cause TLV and an appropriate error condition.
+
+ Note: A positive response is implied if no error is indicated by
+ the sender.
+
+ V3) All responses MUST copy the ASCONF-Request Correlation ID
+ field received in the ASCONF parameter from the TLV being
+ responded to, into the ASCONF-Request Correlation ID field
+ in the response parameter.
+
+ V4) After processing the entire Chunk, the receiver of the
+ ASCONF MUST queue the response ASCONF-ACK Chunk for
+ transmission after the rest of the SCTP packet has been
+ processed. This allows the ASCONF-ACK Chunk to be bundled
+ with other ASCONF-ACK Chunks as well as any additional
+ responses, e.g., a Selective Acknowledgment (SACK) Chunk.
+
+ V5) Update the 'Peer-Sequence-Number' to the value found in the
+ Sequence Number field.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 23]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ E5) Otherwise, the ASCONF Chunk is discarded since it must be either
+ a stale packet or from an attacker. A receiver of such a packet
+ MAY log the event for security purposes.
+
+ E6) When all ASCONF Chunks are processed for this SCTP packet, send
+ back the accumulated single response packet with all of the
+ ASCONF-ACK Chunks. The destination address of the SCTP packet
+ containing the ASCONF-ACK Chunks MUST be the source address of
+ the SCTP packet that held the ASCONF Chunks.
+
+ E7) While processing the ASCONF Chunks in the SCTP packet, if the
+ response packet will exceed the PMTU of the return path, the
+ receiver MUST stop adding additional ASCONF-ACKs into the
+ response packet but MUST continue to process all of the ASCONF
+ Chunks, saving ASCONF-ACK Chunk responses in its cached copy.
+ The sender of the ASCONF Chunk will later retransmit the ASCONF
+ Chunks that were not responded to, at which time the cached
+ copies of the responses that would NOT fit in the PMTU can be
+ sent to the peer.
+
+ Note: These rules have been presented with the assumption that the
+ implementation is caching old ASCONF-ACKs in case of loss of SCTP
+ packets in the ACK path. It is allowable for an implementation to
+ maintain this state in another form it deems appropriate, as long as
+ that form results in the same ASCONF-ACK sequences being returned to
+ the peer as outlined above.
+
+5.3. General Rules for Address Manipulation
+
+ When building TLV parameters for the ASCONF Chunk that will add or
+ delete IP addresses, the following rules MUST be applied:
+
+ F0) If an endpoint receives an ASCONF-ACK that is greater than or
+ equal to the next Sequence Number to be used but no ASCONF Chunk
+ is outstanding, the endpoint MUST ABORT the association. Note
+ that a Sequence Number is greater than if it is no more than
+ 2^^31-1 larger than the current Sequence Number (using serial
+ arithmetic).
+
+ F1) When adding an IP address to an association, the IP address is
+ NOT considered fully added to the association until the ASCONF-
+ ACK arrives. This means that until such time as the ASCONF
+ containing the add is acknowledged, the sender MUST NOT use the
+ new IP address as a source for ANY SCTP packet except on
+ carrying an ASCONF Chunk. The receiver of the Add IP Address
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 24]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ request may use the address as a destination immediately. The
+ receiver MUST use the path-verification procedure for the added
+ address before using that address. The receiver MUST NOT send
+ packets to the new address except for the corresponding ASCONF-
+ ACK Chunk or HEARTBEAT Chunks for path verification before the
+ new path is verified. If the ASCONF-ACK is sent to the new
+ address, it MAY be bundled with the HEARTBEAT chunk for path
+ verification.
+
+ F2) After the ASCONF-ACK of an IP address Add arrives, the endpoint
+ MAY begin using the added IP address as a source address for any
+ type of SCTP chunk.
+
+ F3a) If an endpoint receives an Error Cause TLV indicating that the
+ IP address Add or IP address Deletion parameters was not
+ understood, the endpoint MUST consider the operation failed and
+ MUST NOT attempt to send any subsequent Add or Delete requests
+ to the peer.
+
+ F3b) If an endpoint receives an Error Cause TLV indicating that the
+ IP address Set Primary IP Address parameter was not understood,
+ the endpoint MUST consider the operation failed and MUST NOT
+ attempt to send any subsequent Set Primary IP Address requests
+ to the peer.
+
+ F4) When deleting an IP address from an association, the IP address
+ MUST be considered a valid destination address for the reception
+ of SCTP packets until the ASCONF-ACK arrives and MUST NOT be
+ used as a source address for any subsequent packets. This means
+ that any datagrams that arrive before the ASCONF-ACK destined to
+ the IP address being deleted MUST be considered part of the
+ current association. One special consideration is that ABORT
+ Chunks arriving destined to the IP address being deleted MUST be
+ ignored (see Section 5.3.1 for further details).
+
+ F5) An endpoint MUST NOT delete its last remaining IP address from
+ an association. In other words, if an endpoint is NOT multi-
+ homed, it MUST NOT use the delete IP address without an Add IP
+ Address preceding the delete parameter in the ASCONF Chunk. Or,
+ if an endpoint sends multiple requests to delete IP addresses,
+ it MUST NOT delete all of the IP addresses that the peer has
+ listed for the requester.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 25]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ F6) An endpoint MUST NOT set an IP header source address for an SCTP
+ packet holding the ASCONF Chunk to be the same as an address
+ being deleted by the ASCONF Chunk.
+
+ F7) If a request is received to delete the last remaining IP address
+ of a peer endpoint, the receiver MUST send an Error Cause TLV
+ with the Error Cause set to the new error code 'Request to
+ Delete Last Remaining IP Address'. The requested delete MUST
+ NOT be performed or acted upon, other than to send the ASCONF-
+ ACK.
+
+ F8) If a request is received to delete an IP address that is also
+ the source address of the IP packet that contained the ASCONF
+ chunk, the receiver MUST reject this request. To reject the
+ request, the receiver MUST send an Error Cause TLV set to the
+ new error code 'Request to Delete Source IP Address' (unless
+ Rule F5 has also been violated, in which case the error code
+ 'Request to Delete Last Remaining IP Address' is sent).
+
+ F9) If an endpoint receives an ADD IP Address request and does not
+ have the local resources to add this new address to the
+ association, it MUST return an Error Cause TLV set to the new
+ error code 'Operation Refused Due to Resource Shortage'.
+
+ F10) If an endpoint receives an 'Out of Resource' error in response
+ to its request to ADD an IP address to an association, it must
+ either ABORT the association or not consider the address part of
+ the association. In other words, if the endpoint does not ABORT
+ the association, it must consider the add attempt failed and NOT
+ use this address since its peer will treat SCTP packets destined
+ to the address as Out Of The Blue packets.
+
+ F11) When an endpoint receives an ASCONF to add an IP address sends
+ an 'Out of Resource' in its response, it MUST also fail any
+ subsequent add or delete requests bundled in the ASCONF. The
+ receiver MUST NOT reject an ADD and then accept a subsequent
+ DELETE of an IP address in the same ASCONF Chunk. In other
+ words, once a receiver begins failing any ADD or DELETE request,
+ it must fail all subsequent ADD or DELETE requests contained in
+ that single ASCONF.
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 26]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ F12) When an endpoint receives a request to delete an IP address that
+ is the current primary address, it is an implementation decision
+ as to how that endpoint chooses the new primary address.
+
+ F13) When an endpoint receives a valid request to DELETE an IP
+ address, the endpoint MUST consider the address no longer part
+ of the association. It MUST NOT send SCTP packets for the
+ association to that address and it MUST treat subsequent packets
+ received from that address as Out Of The Blue.
+
+ During the time interval between sending out the ASCONF and
+ receiving the ASCONF-ACK, it MAY be possible to receive DATA
+ Chunks out of order. The following examples illustrate these
+ problems:
+
+ F14) All addresses added by the reception of an ASCONF Chunk MUST be
+ put into the UNCONFIRMED state and MUST have path verification
+ performed on them before the address can be used as described in
+ [RFC4960], Section 5.4.
+
+ Endpoint-A Endpoint-Z
+ ---------- ----------
+ ASCONF[Add-IP:X]------------------------------>
+ /--ASCONF-ACK
+ /
+ /--------/---New DATA:
+ / / Destination
+ <-------------------/ / IP:X
+ /
+ <--------------------------/
+
+ In the above example, we see a new IP address (X) being added to the
+ Endpoint-A. However, due to packet re-ordering in the network, a new
+ DATA chunk is sent and arrives at Endpoint-A before the ASCONF-ACK
+ confirms the add of the address to the association.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 27]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ A similar problem exists with the deletion of an IP address as
+ follows:
+
+ Endpoint-A Endpoint-Z
+ ---------- ----------
+ /------------New DATA:
+ / Destination
+ / IP:X
+ ASCONF [DEL-IP:X]---------/---------------->
+ <-----------------/------------------ASCONF-ACK
+ /
+ /
+ <-------------/
+
+ In this example, we see a DATA chunk destined to the IP:X (which is
+ about to be deleted) arriving after the deletion is complete. For
+ the ADD case, an endpoint SHOULD consider the newly added IP address
+ for the purpose of sending data to the association before the ASCONF-
+ ACK has been received. The endpoint MUST NOT source data from this
+ new address until the ASCONF-ACK arrives, but it may receive out-of-
+ order data as illustrated and MUST NOT treat this data as an OOTB
+ datagram (please see [RFC4960] section 8.4). It MAY drop the data
+ silently or it MAY consider it part of the association, but it MUST
+ NOT respond with an ABORT.
+
+ For the DELETE case, an endpoint MAY respond to the late-arriving
+ DATA packet as an OOTB datagram or it MAY hold the deleting IP
+ address for a small period of time as still valid. If it treats the
+ DATA packet as OOTB, the peer will silently discard the ABORT (since
+ by the time the ABORT is sent, the peer will have removed the IP
+ address from this association). If the endpoint elects to hold the
+ IP address valid for a period of time, it MUST NOT hold it valid
+ longer than 2 RTO intervals for the destination being removed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 28]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+5.3.1. A Special Case for OOTB ABORT Chunks
+
+ Another case worth mentioning is illustrated below:
+
+ Endpoint-A Endpoint-Z
+ ---------- ----------
+
+ New DATA:------------\
+ Source IP:X \
+ \
+ ASCONF-REQ[DEL-IP:X]----\------------------>
+ \ /---------ASCONF-ACK
+ \ /
+ \----/-----------> OOTB
+ (Ignored <---------------------/-------------ABORT
+ by rule F4) /
+ <---------------------/
+
+ For this case, during the deletion of an IP address, an Abort MUST be
+ ignored if the destination address of the Abort message is that of a
+ destination being deleted.
+
+5.3.2. A Special Case for Changing an Address
+
+ In some instances, the sender may only have one IP address in an
+ association that is being renumbered. When this occurs, the sender
+ may not be able to send the appropriate ADD/DELETE pair to the peer,
+ and may use the old address as a source in the IP header. For this
+ reason, the sender MUST fill in the Address Parameter field with an
+ address that is part of the association (in this case, the one being
+ deleted). This will allow the receiver to locate the association
+ without using the source address found in the IP header.
+
+ The receiver of such a chunk MUST always first use the source address
+ found in the IP header in looking up the association. The receiver
+ should attempt to use the address found in the Address Parameter
+ field only if the lookup using the source address from the IP header
+ fails. The receiver MUST reply to the source address of the packet
+ in this case, which is the new address that was added by the ASCONF
+ (since the old address is no longer part of the association after
+ processing).
+
+5.4. Setting of the Primary Address
+
+ A sender of the set primary parameter MAY elect to send this combined
+ with an add or delete of an address. A sender MUST only send a set
+ primary request to an address that is already considered part of the
+ association. In other words, if a sender combines a set primary with
+
+
+
+Stewart, et al. Standards Track [Page 29]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ an add new IP address request, the set primary will be discarded
+ unless the add request is to be processed BEFORE the set primary
+ (i.e., it precedes the set primary).
+
+ A request to set primary MAY also appear in an INIT or INIT-ACK
+ chunk, which can give advice to the peer endpoint as to which of its
+ addresses the sender of the INIT or INIT-ACK would prefer as the
+ primary address.
+
+ The request to set an address as the primary path is an option the
+ receiver SHOULD perform. It is considered advice to the receiver of
+ the best-destination address to use in sending SCTP packets (in the
+ requester's view). If a request arrives that asks the receiver to
+ set an address as primary that does not exist, the receiver SHOULD
+ NOT honor the request, leaving its existing primary address
+ unchanged.
+
+5.5. Bundling of Multiple ASCONFs
+
+ In the normal case, a single ASCONF is sent in a packet and a single
+ reply ASCONF-ACK is received. However, in the event of the loss of
+ an SCTP packet containing either an ASCONF or ASCONF-ACK, it is
+ allowable for a sender to bundle additional ASCONFs in the
+ retransmission. In bundling multiple ASCONFs, the following rules
+ MUST be followed:
+
+ 1. Previously transmitted ASCONF Chunks MUST be left unchanged.
+
+ 2. Each SCTP packet containing ASCONF Chunks MUST be bundled
+ starting with the smallest ASCONF Sequence Number first in the
+ packet (closest to the Chunk header) and preceding in sequential
+ order from the lowest to highest ASCONF Sequence Number.
+
+ 3. All ASCONFs within the packet MUST be adjacent to each other,
+ i.e., no other chunk type must separate the ASCONFs.
+
+ 4. Each new ASCONF lookup address MUST be populated as if the
+ previous ASCONFs had been processed and accepted.
+
+6. Security Considerations
+
+ The addition and or deletion of an IP address to an existing
+ association does provide an additional mechanism by which existing
+ associations can be hijacked. Therefore, this document requires the
+ use of the authentication mechanism defined in [RFC4895] to limit the
+ ability of an attacker to hijack an association.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 30]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Hijacking an association by using the addition and deletion of an IP
+ address is only possible for an attacker who is able to intercept the
+ initial two packets of the association setup when the SCTP-AUTH
+ extension is used without pre-shared keys. If such a threat is
+ considered a possibility, then the [RFC4895] extension MUST be used
+ with a preconfigured shared endpoint pair key to mitigate this
+ threat. For a more detailed analysis, see [RFC4895].
+
+ When the address parameter in ASCONF chunks with Add, IP Delete IP,
+ or Set Primary IP parameters is a wildcard, the source address of the
+ packet is used. This address is not protected by SCTP-AUTH [RFC4895]
+ and an attacker can therefore intercept such a packet and modify the
+ source address. Even if the source address is not one presently an
+ alternate for the association, the identification of the association
+ may rely on the other information in the packet (perhaps the
+ verification tag, for example). An on-path attacker can therefore
+ modify the source address to its liking.
+
+ If the ASCONF includes an Add IP with a wildcard address, the
+ attacker can add an address of its liking, which provides little
+ immediate damage but can set up later attacks.
+
+ If the ASCONF includes a Delete IP with a wildcard address, the
+ attacker can cause all addresses but one of its choosing to be
+ deleted from an association. The address supplied by the attacker
+ must already belong to the association, which makes this more
+ difficult for the attacker. However, the sole remaining address
+ might be one that the attacker controls, for example, or can monitor,
+ etc. In the least, the sender and the deceived receiver would have
+ different ideas of what that sole remaining address would be. This
+ will eventually cause the association to fail, but in the meantime,
+ the deceived receiver could be transmitting packets to an address the
+ sender did not intend.
+
+ If the ASCONF includes a Set Primary IP with a wildcard address, then
+ the attacker can cause an address to be used as a primary address.
+ This is limited to an address that already belongs to the
+ association, so the damage is limited. At least, the result would be
+ that the recipient is using a primary address that the sender did not
+ intend. However, if both a wildcard Add IP and a wildcard Set
+ Primary IP are used, then the attacker can modify the source address
+ to both add an address to its liking to the association and make it
+ the primary address. Such a combination would present the attacker
+ with an opportunity for more damage.
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 31]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Note that all these attacks are from an on-path attacker. Endpoints
+ that believe they face a threat from on-path attackers SHOULD NOT use
+ wildcard addresses in ASCONF Add IP, Delete IP, or Set Primary IP
+ parameters.
+
+ If an SCTP endpoint that supports this extension receives an INIT
+ that indicates that the peer supports the ASCONF extension but does
+ NOT support the [RFC4895] extension, the receiver of such an INIT
+ MUST send an ABORT in response. Note that an implementation is
+ allowed to silently discard such an INIT as an option as well, but
+ under NO circumstance is an implementation allowed to proceed with
+ the association setup by sending an INIT-ACK in response.
+
+ An implementation that receives an INIT-ACK that indicates that the
+ peer does not support the [RFC4895] extension MUST NOT send the
+ COOKIE-ECHO to establish the association. Instead, the
+ implementation MUST discard the INIT-ACK and report to the upper-
+ layer user that an association cannot be established destroying the
+ Transmission Control Block (TCB).
+
+ Other types of attacks, e.g., bombing, are discussed in detail in
+ [RFC5062]. The bombing attack, in particular, is countered by the
+ use of a random nonce and is required by [RFC4960].
+
+ An on-path attacker can modify the INIT and INIT-ACK Supported
+ Extensions parameter (and authentication-related parameters) to
+ produce a denial of service. If the on-path attacker removes the
+ [RFC4895]-related parameters from an INIT that indicates it supports
+ the ASCONF extension, the association will not be established. If
+ the on-path attacker adds a Supported Extensions parameter mentioning
+ the ASCONF type to an INIT or INIT-ACK that does not carry any AUTH-
+ related parameters, the association will not be established. If the
+ on-path attacker removes the Supported Extensions parameter (or
+ removes the ASCONF type from that parameter) from the INIT or the
+ INIT-ACK, then the association will not be able to use the ADD-IP
+ feature. If the on-path attacker adds the Supported Extensions
+ parameter listing the ASCONF type to an INIT-ACK that did not carry
+ one (but did carry AUTH-related parameters), then the INIT sender may
+ use ASCONF where the INIT-ACK sender does not support it. This would
+ be discovered later if the INIT sender transmitted an ASCONF, but the
+ INIT sender could have made configuration choices at that point. As
+ the INIT and INIT-ACK are not protected by the AUTH feature, there is
+ no way to counter such attacks. Note however that an on-path
+ attacker capable of modifying the INIT and INIT-ACK would almost
+ certainly also be able to prevent the INIT and INIT-ACK from being
+ delivered or modify the verification tags or checksum to cause the
+ packet to be discarded, so the Supported Extensions adds little
+ additional vulnerability (with respect to preventing association
+
+
+
+Stewart, et al. Standards Track [Page 32]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ formation) to the SCTP protocol. The ability to prevent the use of
+ this new feature is an additional vulnerability to SCTP but only for
+ this new feature.
+
+ The Adaptation Layer Indication is subject to corruption, insertion,
+ or deletion from the INIT and INIT-ACK chunks by an on-path attacker.
+ This parameter SHOULD be opaque to the SCTP protocol (see Section
+ 4.2.6), and so changes to the parameter will likely not affect the
+ SCTP protocol. However, any adaptation layer that is defined SHOULD
+ consider its own vulnerabilities in the Security Considerations
+ section of the RFC that defines its adaptation code point.
+
+ The Set Primary IP Address parameter is subject to corruption,
+ insertion, or deletion by an on-path attacker when included in the
+ INIT and INIT-ACK chunks. The attacker could use this to influence
+ the receiver to choose an address to its own purposes (one over which
+ it has control, one that would be less desirable for the sender,
+ etc.). An on-path attacker would also have the ability to include or
+ remove addresses for the association from the INIT or INIT-ACK, so it
+ is not limited in the address it can specify in the Set Primary IP
+ Address. Endpoints that wish to avoid this possible threat MAY defer
+ sending the initial Set Primary request and wait until the
+ association is fully established before sending a fully protected
+ ASCONF with the Set Primary as its single parameter.
+
+7. IANA Considerations
+
+ This document defines the following new SCTP parameters, chunks, and
+ errors (http://www.iana.org/assignments/sctp-parameters):
+
+ o two new chunk types,
+
+ o six parameter types, and
+
+ o five new SCTP error causes.
+
+ The chunk types with their assigned values are shown below.
+
+ Chunk Type Chunk Name
+ --------------------------------------------------------------
+ 0xC1 Address Configuration Change Chunk (ASCONF)
+ 0x80 Address Configuration Acknowledgment (ASCONF-ACK)
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 33]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ The parameter types are listed below:
+
+ Parameter Type Parameter Name
+ -------------------------------------------------
+ 0x8008 Supported Extensions
+ 0xC001 Add IP Address
+ 0xC002 Delete IP Address
+ 0xC003 Error Cause Indication
+ 0xC004 Set Primary Address
+ 0xC005 Success Indication
+ 0xC006 Adaptation Layer Indication
+
+ The Error Causes are listed below:
+
+ Cause Code
+ Value Cause Code
+ --------- ----------------
+ 0x00A0 Request to Delete Last Remaining IP Address
+ 0x00A1 Operation Refused Due to Resource Shortage
+ 0x00A2 Request to Delete Source IP Address
+ 0x00A3 Association Aborted Due to Illegal ASCONF-ACK
+ 0x00A4 Request Refused - No Authorization
+
+ This document also defines an adaptation code point. The adaptation
+ code point is a 32-bit integer that is assigned by IANA through an
+ IETF Consensus action as defined in [RFC2434]. For this new
+ registry, no initial values are being added by this document;
+ however, [RDDP] will add the first entry.
+
+8. Acknowledgments
+
+ The authors would like to express a special note of thanks to Michael
+ Ramahlo and Phillip Conrad for their extreme efforts in the early
+ formation of this draft.
+
+ The authors wish to thank Jon Berger, Mark Butler, Lars Eggert,
+ Janardhan Iyengar, Greg Kendall, Seok Koh, Salvatore Loreto, Peter
+ Lei, John Loughney, Sandy Murphy, Ivan Arias Rodriguez, Renee Revis,
+ Marshall Rose, Ronnie Sellars, Chip Sharp, and Irene Ruengeler for
+ their invaluable comments.
+
+ The authors would also like to give special mention to Maria-Carmen
+ Belinchon and Ian Rytina for their early contributions to this
+ document and their thoughtful comments.
+
+ And a special thanks to James Polk, abstract writer to the few but
+ lucky.
+
+
+
+
+Stewart, et al. Standards Track [Page 34]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+9. References
+
+9.1. Normative References
+
+ [RFC1122] Braden, R., "Requirements for Internet Hosts -
+ Communication Layers", STD 3, RFC 1122, October 1989.
+
+ [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,
+ August 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
+ IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6
+ (IPv6) Specification", RFC 2460, December 1998.
+
+ [RFC4960] Stewart, R., Ed., "Stream Control Transmission Protocol",
+ RFC 4960, September 2007.
+
+ [RFC4895] Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+ "Authenticated Chunks for the Stream Control Transmission
+ Protocol (SCTP)", RFC 4895, August 2007.
+
+9.2. Informative References
+
+ [RFC5062] Stewart, R., Tuexen, M., and G. Camarillo, "Security
+ Attacks Found Against SCTP and Current Countermeasures",
+ RFC 5062, September 2007.
+
+ [RDDP] Bestler, C. and R. Stewart, "Stream Control Transmission
+ Protocol (SCTP) Direct Data Placement (DDP) Adaptation",
+ Work in Progress, September 2006.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 35]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+Appendix A. Abstract Address Handling
+
+A.1. General Remarks
+
+ This appendix is non-normative. It is present to give the reader a
+ concise mathematical definition of an SCTP endpoint. The following
+ text provides a working definition of the endpoint notion to discuss
+ address reconfiguration. It is not intended to restrict
+ implementations in any way; its goal is to provide a set of
+ definitions only. Using these definitions should make a discussion
+ about address issues easier.
+
+A.2. Generalized Endpoints
+
+ A generalized endpoint is a pair of a set of IP addresses and a port
+ number at any given point of time. The precise definition is as
+ follows:
+
+ A generalized endpoint gE at time t is given by
+
+ gE(t) = ({IP1, ..., IPn}, Port)
+
+ where {IP1, ..., IPn} is a non-empty set of IP addresses.
+
+ Please note that the dynamic addition and deletion of IP addresses
+ described in this document allows the set of IP addresses of a
+ generalized endpoint to be changed at some point of time. The port
+ number can never be changed.
+
+ The set of IP addresses of a generalized endpoint gE at a time t is
+ defined as
+
+ Addr(gE)(t) = {IP1, ..., IPn}
+
+ if gE(t) = ({IP1, ..., IPn}, Port) holds at time t.
+
+ The port number of a generalized endpoint gE is defined as
+
+ Port(gE) = Port
+
+ if gE(t) = ({IP1, ..., IPn}, Port) holds at time t.
+
+ There is one fundamental rule that restricts all generalized
+ endpoints:
+
+ For two different generalized endpoints gE' and gE'' with the same
+ port number Port(gE') = Port(gE''), the address sets Addr(gE')(t) and
+ Addr(gE'')(t) must be disjoint at every point in time.
+
+
+
+Stewart, et al. Standards Track [Page 36]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+A.3. Associations
+
+ Associations consist of two generalized endpoints and the two address
+ sets known by the peer at any time. The precise definition is as
+ follows:
+
+ An association A between two different generalized endpoints gE' and
+ gE'' is given by
+
+ A = (gE', S', gE'', S'')
+
+ where S'(t) and S''(t) are a set of addresses at any time t such that
+ S'(t) is a non-empty subset of Addr(gE')(t) and S''(t) is a non-empty
+ subset of Addr(gE'')(t).
+
+ If A = (gE', S', gE'', S'') is an association between the generalized
+ endpoints gE' and gE'', the following notion is used:
+
+ Addr(A, gE') = S' and Addr(A, gE'') = S''.
+
+ If the dependency on time is important the notion Addr(A, gE')(t) =
+ S'(t) will be used.
+
+ If A is an association between gE' and gE'', then Addr(A, gE') is the
+ subset of IP addresses of gE', which is known by gE'' and used by
+ gE'.
+
+ Association establishment between gE' and gE'' can be seen as:
+
+ 1. gE' and gE'' do exist before the association.
+
+ 2. If an INIT has to be sent from gE' to gE'', address-scoping rules
+ and other limitations are applied to calculate the subset S' from
+ Addr(gE'). The addresses of S' are included in the INIT chunk.
+
+ 3. If an INIT-ACK has to be sent from gE'' to gE', address-scoping
+ rules and other limitations are applied to calculate the subset
+ S'' from Addr(gE''). The addresses of S'' are included in the
+ INIT-ACK chunk.
+
+ 4. After the handshake the association A = (gE', S', gE'', S'') has
+ been established.
+
+ 5. Right after the association establishment Addr(A, gE') and
+ Addr(A, gE'') are the addresses that have been seen on the wire
+ during the handshake.
+
+
+
+
+
+Stewart, et al. Standards Track [Page 37]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+A.4. Relationship with RFC 4960
+
+ [RFC4960] defines the notion of an endpoint. This subsection will
+ show that these endpoints are also (special) generalized endpoints.
+
+ [RFC4960] has no notion of address-scoping or other address-handling
+ limitations and provides no mechanism to change the addresses of an
+ endpoint.
+
+ This means that an endpoint is simply a generalized endpoint that
+ does not depend on time. Neither the port nor the address list
+ changes.
+
+ During association setup, no address-scoping rules or other
+ limitations will be applied. This means that for an association A
+ between two endpoints gE' and gE'', the following is true:
+
+ Addr(A, gE') = Addr(gE') and Addr(A, gE'') = Addr(gE'').
+
+A.5. Rules for Address Manipulation
+
+ The rules for address manipulation can now be stated in a simple way:
+
+ 1. An address can be added to a generalized endpoint gE only if this
+ address is not an address of a different generalized endpoint
+ with the same port number.
+
+ 2. An address can be added to an association A with generalized
+ endpoint gE if it has been added to the generalized endpoint gE
+ first. This means that the address must be an element of
+ Addr(gE) first and then it can become an element of Addr(A, gE).
+ But this is not necessary. If the association does not allow the
+ reconfiguration of the addresses only Addr(gE) can be modified.
+
+ 3. An address can be deleted from an association A with generalized
+ endpoint gE as long as Addr(A, gE) stays non-empty.
+
+ 4. An address can be deleted from an generalized endpoint gE only if
+ it has been removed from all associations having gE as a
+ generalized endpoint.
+
+ These rules simply make sure that the rules for the endpoints and
+ associations given above are always fulfilled.
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 38]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+Authors' Addresses
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 4875 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ US
+
+ Phone:
+ EMail: rrs@cisco.com
+
+
+ Qiaobing Xie
+ Motorola, Inc.
+ 1501 W. Shure Drive, 2-3C
+ Arlington Heights, IL 60004
+ USA
+
+ Phone: +1-847-632-3028
+ EMail: Qiaobing.Xie@motorola.com
+
+
+ Michael Tuexen
+ Univ. of Applied Sciences Muenster
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Shin Maruyama
+ Kyoto University
+ Yoshida-Honmachi
+ Sakyo-ku
+ Kyoto, Kyoto 606-8501
+ JAPAN
+
+ Phone: +81-75-753-7417
+ EMail: mail@marushin.gr.jp
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 39]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+ Masahiro Kozuka
+ Kyoto University
+ Yoshida-Honmachi
+ Sakyo-ku
+ Kyoto, Kyoto 606-8501
+ JAPAN
+
+ Phone: +81-75-753-7417
+ EMail: ma-kun@kozuka.jp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 40]
+
+RFC 5061 SCTP Dynamic Address Reconfiguration September 2007
+
+
+Full Copyright Statement
+
+ Copyright (C) The IETF Trust (2007).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+ THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Standards Track [Page 41]
+
diff --git a/doc/rfc5062.txt b/doc/rfc5062.txt
new file mode 100644
index 0000000..d008c9d
--- /dev/null
+++ b/doc/rfc5062.txt
@@ -0,0 +1,787 @@
+
+
+
+
+
+
+<.
+Network Working Group R. Stewart
+Request for Comments: 5062 Cisco Systems, Inc.
+Category: Informational M. Tuexen
+ Muenster Univ. of Applied Sciences
+ G. Camarillo
+ Ericsson
+ September 2007
+
+
+ Security Attacks Found Against
+ the Stream Control Transmission Protocol (SCTP)
+ and Current Countermeasures
+
+Status of This Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Abstract
+
+ This document describes certain security threats to SCTP. It also
+ describes ways to mitigate these threats, in particular by using
+ techniques from the SCTP Specification Errata and Issues memo (RFC
+ 4460). These techniques are included in RFC 4960, which obsoletes
+ RFC 2960. It is hoped that this information will provide some useful
+ background information for many of the newest requirements spelled
+ out in the SCTP Specification Errata and Issues and included in RFC
+ 4960.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 1]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 2. Address Camping or Stealing . . . . . . . . . . . . . . . . . 2
+ 3. Association Hijacking 1 . . . . . . . . . . . . . . . . . . . 3
+ 4. Association Hijacking 2 . . . . . . . . . . . . . . . . . . . 6
+ 5. Bombing Attack (Amplification) 1 . . . . . . . . . . . . . . . 7
+ 6. Bombing Attack (Amplification) 2 . . . . . . . . . . . . . . . 9
+ 7. Association Redirection . . . . . . . . . . . . . . . . . . . 10
+ 8. Bombing Attack (Amplification) 3 . . . . . . . . . . . . . . . 10
+ 9. Bombing Attack (Amplification) 4 . . . . . . . . . . . . . . . 11
+ 10. Bombing Attack (amplification) 5 . . . . . . . . . . . . . . . 11
+ 11. Security Considerations . . . . . . . . . . . . . . . . . . . 12
+ 12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 12
+
+1. Introduction
+
+ Stream Control Transmission Protocol, originally defined in
+ [RFC2960], is a multi-homed transport protocol. As such, unique
+ security threats exists that are addressed in various ways within the
+ protocol itself. This document describes certain security threats to
+ SCTP. It also describes ways to mitigate these threats, in
+ particular by using techniques from the SCTP Specification Errata and
+ Issues memo [RFC4460]. These techniques are included in [RFC4960],
+ which obsoletes [RFC2960]. It is hoped that this information will
+ provide some useful background information for many of the newest
+ requirements spelled out in the [RFC4460] and included in [RFC4960].
+
+ This work and some of the changes that went into [RFC4460] and
+ [RFC4960] are much indebted to the paper on potential SCTP security
+ risks [EFFECTS] by Aura, Nikander, and Camarillo. Without their
+ work, some of these changes would remain undocumented and potential
+ threats.
+
+ The rest of this document will concentrate on the various attacks
+ that were illustrated in [EFFECTS] and detail the preventative
+ measures now in place, if any, within the current SCTP standards.
+
+2. Address Camping or Stealing
+
+ This attack is a form of denial of service attack crafted around
+ SCTP's multi-homing. In effect, an illegitimate endpoint connects to
+ a server and "camps upon" or "holds up" a valid peer's address. This
+ is done to prevent the legitimate peer from communicating with the
+ server.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 2]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+2.1. Attack Details
+
+ +----------+ +----------+ +----------+
+ | Evil | | Server | | Client |
+ | IP-A=+------------+ +-----------+=IP-C & D |
+ | Attacker | | | | Victim |
+ +----------+ +----------+ +----------+
+
+ Figure 1: Camping
+
+ Consider the scenario illustrated in Figure 1. The attacker
+ legitimately holds IP-A and wishes to prevent the 'Client-Victim'
+ from communicating with the 'Server'. Note also that the client is
+ multi-homed. The attacker first guesses the port number our client
+ will use in its association attempt. It then uses this port and sets
+ up an association with the server listing not only IP-A but also IP-C
+ in its initial INIT chunk. The server will respond and set up the
+ association, noting that the attacker is multi-homed and holds both
+ IP-A and IP-C.
+
+ Next, the victim sends in an INIT message listing its two valid
+ addresses, IP-C and IP-D. In response, it will receive an ABORT
+ message with possibly an error code indicating that a new address was
+ added in its attempt to set up an existing association (a restart
+ with new addresses). At this point, 'Client-Victim' is now prevented
+ from setting up an association with the server until the server
+ realizes that the attacker does not hold the address IP-C at some
+ future point by using a HEARTBEAT based mechanism. See the
+ mitigation option subsection of this section.
+
+2.2. Analysis
+
+ This particular attack was discussed in detail on the SCTP
+ implementors list in March of 2003. Out of that discussion, changes
+ were made in the BSD implementation that are now present in
+ [RFC4960]. In close examination, this attack depends on a number of
+ specific things to occur.
+
+ 1) The attacker must set up the association before the victim and
+ must correctly guess the port number that the victim will use. If
+ the victim uses any other port number the attack will fail.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 3]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+ 2) SCTP's existing HEARTBEAT mechanism as defined already in
+ [RFC2960] will eventually catch this situation and abort the evil
+ attacker's association. This may take several seconds based on
+ default HEARTBEAT timers but the attacker himself will lose any
+ association.
+
+ 3) If the victim is either not multi-homed, or the address set that
+ it uses is completely camped upon by the attacker (in our example
+ if the attacker had included IP-D in its INIT as well), then the
+ client's INIT message would initiate an association between the
+ client and the server while destroying the association between the
+ attacker and the server. From the servers' perspective, this is a
+ restart of the association.
+
+2.3. Mitigation Option
+
+ [RFC4960] adds a new set of requirements to better counter this
+ attack. In particular, the HEARTBEAT mechanism was modified so that
+ addresses unknown to an endpoint (i.e., presented in an INIT with no
+ pre-knowledge given by the application) enter a new state called
+ "UNCONFIRMED". During the time that any address is UNCONFIRMED and
+ yet considered available, heartbeating will be done on those
+ UNCONFIRMED addresses at an accelerated rate. This will lessen the
+ time that an attacker can "camp" on an address. In particular, the
+ rate of heartbeats to UNCONFIRMED addresses is done every RTO. Along
+ with this expanded rate of heartbeating, a new 64-bit random nonce is
+ required to be inside HEARTBEATs to UNCONFIRMED addresses. In the
+ HEARTBEAT-ACK, the random nonce must match the value sent in the
+ HEARTBEAT before an address can leave the UNCONFIRMED state. This
+ will prevent an attacker from generating false HEARTBEAT-ACKs with
+ the victim's source address(es). In addition, clients that do not
+ need to use a specific port number should choose their port numbers
+ on a random basis. This makes it hard for an attacker to guess that
+ number.
+
+3. Association Hijacking 1
+
+ Association hijacking is the ability of some other user to assume the
+ session created by another endpoint. In cases of a true man-in-the-
+ middle, only a strong end-to-end security model can prevent this.
+ However, with the addition of the SCTP extension specified in
+ [RFC5061], an endpoint that is NOT a man-in-the-middle may be able to
+ assume another endpoint's association.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 4]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+3.1. Attack Details
+
+ The attack is made possible by any mechanism that lets an endpoint
+ acquire some other IP address that was recently in use by an SCTP
+ endpoint. For example, DHCP may be used in a mobile network with
+ short IP address lifetimes to reassign IP addresses to migrant hosts.
+
+ IP-A DHCP-Server's Peer-Server
+ |
+ |
+ 1 |-DHCP-Rel(IP-A)---->|
+ 2 |------ASCONF(ADD-IP(IP-B), DEL-IP(IP-A)---->XXlost
+ time
+ |
+ |-DHCP-new-net------>|
+ 3 |<---Assign (IP-A)
+ |
+ 4 |<------------Tag:X-DATA()------------------
+ |
+ |-------------INIT()------------------------>
+ 5 |<------------INIT-ACK()---------------------
+ |
+ 6 |----ASCONF(ADD-IP(IP-Z),DEL-IP(IP-A))------>
+
+ Figure 2: Association Hijack via DHCP
+
+ At point 1, our valid client releases the IP address IP-A. It
+ presumably acquires a new address (IP-B) and sends an ASCONF to ADD
+ the new address and delete to old address at point 2, but this packet
+ is lost. Thus, our peer (Peer-Server) has no idea that the former
+ peer is no longer at IP-A. Now at point 3, a new "evil" peer obtains
+ an address via DHCP and it happens to get the re-assigned address
+ IP-A. Our Peer-Server sends a chunk of DATA at point 4. This
+ reveals to the new owner of IP-A that the former owner of IP-A had an
+ association with Peer-Server. So at point 5, the new owner of IP-A
+ sends an INIT. The INIT-ACK is sent back and inside it is a COOKIE.
+ The cookie would of course hold tie-tags, which would list both sets
+ of tags that could then be used at point 6 to add in any other IP
+ addresses that the owner of IP-A holds and thus acquire the
+ association.
+
+ It should be noted that this attack is possible in general whenever
+ the attacker is able to send packets with source address IP-A and
+ receive packets with destination address IP-A.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 5]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+3.2. Analysis
+
+ This attack depends on a number of events:
+
+ 1) Both endpoints must support the SCTP extension specified in
+ [RFC5061].
+
+ 2) One of the endpoints must be using the SCTP extension for mobility
+ specified in [RFC5061].
+
+ 3) The IP address must be acquired in such a way as to make the
+ endpoint the owner of that IP address as far as the network is
+ concerned.
+
+ 4) The true peer must not receive the ASCONF packet that deletes IP-A
+ and adds its new address to the peer before the new "evil" peer
+ gets control of the association.
+
+ 5) The new "evil" peer must have an alternate address, aside from the
+ IP-A that it can add to the association, so it can delete IP-A,
+ preventing the real peer from re-acquiring the association when it
+ finally retransmits the ASCONF (from step 2).
+
+3.3. Mitigation Option
+
+ [RFC4960] adds a new counter measure to this threat. It is now
+ required that Tie-Tags in the State-Cookie parameter not be the
+ actual tags. Instead, a new pair of two 32-bit nonces must be used
+ to represent the real tags within the association. This prevents the
+ attacker from acquiring the real tags and thus prevents this attack.
+ Furthermore, the use of the SCTP extension specified in [RFC5061]
+ requires the use of the authentication mechanism defined in
+ [RFC4895]. This requires the attacker to be able to capture the
+ traffic during the association setup. If in addition an endpoint-
+ pair shared key is used, capturing or intercepting these setup
+ messages does not enable the attacker to hijack the association.
+
+4. Association Hijacking 2
+
+ Association hijacking is the ability of some other user to assume the
+ session created by another endpoint. In cases where an attacker can
+ send packets using the victims IP-address as a source address and can
+ receive packets with the victims' address as a destination address,
+ the attacker can easily restart the association. If the peer does
+ not pay attention to the restart notification, the attacker has taken
+ over the association.
+
+
+
+
+
+Stewart, et al. Informational [Page 6]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+4.1. Attack Details
+
+ Assume that an endpoint E1 having an IP-address A has an SCTP
+ association with endpoint E2. After the attacker is able to receive
+ packets to destination address A and send packets with source address
+ A, the attacker can perform a full four-way handshake using the IP-
+ addresses and port numbers from the received packet. E2 will
+ consider this a restart of the association. If and only if the SCTP
+ user of E2 does not process the restart notification, the user will
+ not recognize that the association just restarted. From this
+ perspective, the association has been hijacked.
+
+4.2. Analysis
+
+ This attack depends on a number of circumstances:
+
+ 1) The IP address must be acquired in such a way as to make the evil
+ endpoint the owner of that IP address as far as the network or
+ local LAN is concerned.
+
+ 2) The attacker must receive a packet belonging to the association or
+ connection.
+
+ 3) The other endpoint's user does not pay attention to restart
+ notifications.
+
+4.3. Mitigation Option
+
+ It is important to note that this attack is not based on a weakness
+ of the protocol, but on the ignorance of the upper layer. This
+ attack is not possible if the upper layer processes the restart
+ notifications provided by SCTP as described in section 10 of
+ [RFC2960] or [RFC4960]. Note that other IP protocols may also be
+ affected by this attack.
+
+5. Bombing Attack (Amplification) 1
+
+ The bombing attack is a method to get a server to amplify packets to
+ an innocent victim.
+
+5.1. Attack Details
+
+ This attack is performed by setting up an association with a peer and
+ listing the victims IP address in the INIT's list of addresses.
+ After the association is setup, the attacker makes a request for a
+ large data transfer. After making the request, the attacker does not
+ acknowledge data sent to it. This then causes the server to re-
+ transmit the data to the alternate address, i.e., that of the victim.
+
+
+
+Stewart, et al. Informational [Page 7]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+ After waiting an appropriate time period, the attacker acknowledges
+ the data for the victim. At some point, the attackers address is
+ considered unreachable since only data sent to the victims address is
+ acknowledged. At this point, the attacker can send strategic
+ acknowledgments so that the server continues to send data to the
+ victim.
+
+ Alternatively, instead of stopping the sending of SACKs to enforce a
+ path failover, the attacker can use the ADD-IP extension to add the
+ address of the victim and make that address the primary path.
+
+5.2. Analysis
+
+ This attack depends on a number of circumstances:
+
+ 1) The victim must NOT support SCTP, otherwise it would respond with
+ an "out of the blue" (OOTB) abort.
+
+ 2) The attacker must time its sending of acknowledgments correctly in
+ order to get its address into the failed state and the victim's
+ address as the only valid alternative.
+
+ 3) The attacker must guess TSN values that are accepted by the
+ receiver once the bombing begins since it must acknowledge packets
+ it is no longer seeing.
+
+5.3. Mitigation Option
+
+ [RFC4960] makes two changes to prevent this attack. First, it
+ details proper handling of ICMP messages. With SCTP, the ICMP
+ messages provide valuable clues to the SCTP stack that can be
+ verified with the tags for authenticity. Proper handling of an ICMP
+ protocol unreachable (or equivalent) would cause the association
+ setup by the attacker to be immediately failed upon the first
+ retransmission to the victim's address.
+
+ The second change made in [RFC4960] is the requirement that no
+ address that is not CONFIRMED is allowed to have DATA chunks sent to
+ it. This prevents the switch-over to the alternate address from
+ occurring, even when ICMP messages are lost in the network and
+ prevents any DATA chunks from being sent to any other destination
+ other then the attacker itself. This also prevents the alternative
+ way of using ADD-IP to add the new address and make it the primary
+ address.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 8]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+ An SCTP implementation should abort the association if it receives a
+ SACK acknowledging a TSN that has not been sent. This makes TSN
+ guessing for the attacker quite hard because if the attacker
+ acknowledges one TSN too fast, the association will be aborted.
+
+6. Bombing Attack (Amplification) 2
+
+ This attack allows an attacker to use an arbitrary SCTP endpoint to
+ send multiple packets to a victim in response to one packet.
+
+6.1. Attack Details
+
+ The attacker sends an INIT listing multiple IP addresses of the
+ victim in the INIT's list of addresses to an arbitrary endpoint.
+ Optionally, it requests a long cookie lifetime. Upon reception of
+ the INIT-ACK, it stores the cookie and sends it back to the other
+ endpoint. When the other endpoint receives the COOKIE, it will send
+ back a COOKIE-ACK to the attacker and up to HB.Max.Burst HEARTBEATS
+ to the victim's address(es) (to confirm these addresses). The victim
+ responds with ABORTs or ICMP messages resulting in the removal of the
+ TCB at the other endpoint. The attacker can now resend the stored
+ cookie as long as it is valid, and this will again result in up to
+ HB.Max.Burst HEARTBEATs sent to the victim('s).
+
+6.2. Analysis
+
+ The multiplication factor is limited by the number of addresses of
+ the victim and of the endpoint HB.Max.Burst. Also, the shorter the
+ cookie lifetime, the earlier the attacker has to go through the
+ initial stage of sending an INIT instead of just sending the COOKIE.
+ It should also be noted that the attack is more effective if large
+ HEARTBEATs are used for path confirmation.
+
+6.3. Mitigation Option
+
+ To limit the effectiveness of this attack, the new parameter
+ HB.Max.Burst was introduced in [RFC4960] and an endpoint should:
+
+ 1) not allow very large cookie lifetimes, even if they are requested.
+
+ 2) not use larger HB.Max.Burst parameter values than recommended.
+ Note that an endpoint may decide to send only one Heartbeat per
+ RTT instead of the maximum (i.e., HB.Max.Burst). An endpoint that
+ chooses this approach will however slow down detection of
+ endpoints camping on valid addresses.
+
+ 3) not use large HEARTBEATs for path confirmation.
+
+
+
+
+Stewart, et al. Informational [Page 9]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+7. Association Redirection
+
+ This attack allows an attacker to wrongly set up an association to a
+ different endpoint.
+
+7.1. Attack Details
+
+ The attacker sends an INIT sourced from port 'X' and directed towards
+ port 'Y'. When the INIT-ACK is returned, the attacker sends the
+ COOKIE-ECHO chunk and either places a different destination or source
+ port in the SCTP common header, i.e., X+1 or Y+1. This possibly sets
+ up the association using the modified port numbers.
+
+7.2. Analysis
+
+ This attack depends on the failure of an SCTP implementation to store
+ and verify the ports within the COOKIE structure.
+
+7.3. Mitigation Option
+
+ This attack is easily defeated by an implementation including the
+ ports of both the source and destination within the COOKIE. If the
+ source and destination ports do not match those within the COOKIE
+ chunk when the COOKIE is returned, the SCTP implementation silently
+ discards the invalid COOKIE.
+
+8. Bombing Attack (Amplification) 3
+
+ This attack allows an attacker to use an SCTP endpoint to send a
+ large number of packets in response to one packet.
+
+8.1. Attack Details
+
+ The attacker sends a packet to an SCTP endpoint, which requires the
+ sending of multiple chunks. If the SCTP endpoint does not support
+ bundling on the sending side, it might send each chunk per packet.
+ These packets can either be sent to a victim by using the victim's
+ address as the sources address, or it can be considered an attack
+ against the network. Since the chunks, which need to be sent in
+ response to the received packet, may not fit into one packet, an
+ endpoint supporting bundling on the sending side might send multiple
+ packets.
+
+ Examples of these packets are packets containing a lot of unknown
+ chunks that require an ERROR chunk to be sent, known chunks that
+ initiate the sending of ERROR chunks, packets containing a lot of
+ HEARTBEAT chunks, and so on.
+
+
+
+
+Stewart, et al. Informational [Page 10]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+8.2. Analysis
+
+ This attack depends on the fact that the SCTP endpoint does not
+ support bundling on the sending side or provides a bad implementation
+ of bundling on the sending side.
+
+8.3. Mitigation Option
+
+ First of all, path verification must happen before sending chunks
+ other than HEARTBEATs for path verification. This ensures that the
+ above attack cannot be used against other hosts. To avoid the
+ attack, an SCTP endpoint should implement bundling on the sending
+ side and should not send multiple packets in response. If the SCTP
+ endpoint does not support bundling on the sending side, it should not
+ send in general more than one packet in response to a received one.
+ The details of the required handling are described in [RFC4960].
+
+9. Bombing Attack (Amplification) 4
+
+ This attack allows an attacker to use an SCTP server to send a larger
+ packet to a victim than it sent to the SCTP server.
+
+9.1. Attack Details
+
+ The attacker sends packets using the victim's address as the source
+ address containing an INIT chunk to an SCTP Server. The server then
+ sends a packet containing an INIT-ACK chunk to the victim, which is
+ most likely larger than the packet containing the INIT.
+
+9.2. Analysis
+
+ This attack is a byte and not a packet amplification attack and,
+ without protocol changes, is hard to avoid. A possible method to
+ avoid this attack would be the usage the PAD parameter defined in
+ [RFC4820].
+
+9.3. Mitigation Option
+
+ A server should be implemented in a way that the generated INIT-ACK
+ chunks are as small as possible.
+
+10. Bombing Attack (amplification) 5
+
+ This attack allows an attacker to use an SCTP endpoint to send a
+ large number of packets in response to one packet.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 11]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+10.1. Attack Details
+
+ The attacker sends a packet to an SCTP endpoint, which requires the
+ sending of multiple chunks. If the MTU towards the attacker is
+ smaller than the MTU towards the victim, the victim might need to
+ send more than one packet to send all the chunks. The difference
+ between the MTUs might be extremely large if the attacker sends
+ malicious ICMP packets to make use of the path MTU discovery.
+
+10.2. Analysis
+
+ This attack depends on the fact that an SCTP implementation might not
+ limit the number of response packets correctly.
+
+10.3. Mitigation Option
+
+ First of all, path verification must happen before sending chunks
+ other than HEARTBEATs for path verification. This makes sure that
+ the above attack cannot be used against other hosts. To avoid the
+ attack, an SCTP endpoint should not send multiple packets in response
+ to a single packet. The chunks not fitting in this packet should be
+ dropped.
+
+11. Security Considerations
+
+ This document is about security; as such, there are no additional
+ security considerations.
+
+12. References
+
+12.1. Normative References
+
+ [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+ Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
+ Zhang, L., and V. Paxson, "Stream Control Transmission
+ Protocol", RFC 2960, October 2000.
+
+ [RFC4460] Stewart, R., Arias-Rodriguez, I., Poon, K., Caro, A., and
+ M. Tuexen, "Stream Control Transmission Protocol (SCTP)
+ Specification Errata and Issues", RFC 4460, April 2006.
+
+ [RFC4820] Tuexen, M., Stewart, R., and P. Lei, "Padding Chunk and
+ Parameter for the Stream Control Transmission Protocol
+ (SCTP)", RFC 4820, March 2007.
+
+ [RFC4895] Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+ "Authenticated Chunks for Stream Control Transmission
+ Protocol (SCTP)", RFC 4895, August 2007.
+
+
+
+Stewart, et al. Informational [Page 12]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+ [RFC5061] Stewart, R., Xie, Q., Tuexen, M., Maruyama, S., and M.
+ Kozuka, "Stream Control Transmission Protocol (SCTP)
+ Dynamic Address Reconfiguration", RFC 5061,
+ September 2007.
+
+ [RFC4960] Stewart, R., Ed., "Stream Control Transmission Protocol",
+ RFC 4960, June 2007.
+
+12.2. Informative References
+
+ [EFFECTS] Aura, T., Nikander, P., and G. Camarillo, "Effects of
+ Mobility and Multihoming on Transport-Layer Security",
+ Security and Privacy 2004, IEEE Symposium , URL http://
+ research.microsoft.com/users/tuomaura/Publications/
+ aura-nikander-camarillo-ssp04.pdf, May 2004.
+
+Authors' Addresses
+
+ Randall R. Stewart
+ Cisco Systems, Inc.
+ 4785 Forest Drive
+ Suite 200
+ Columbia, SC 29206
+ USA
+
+ EMail: rrs@cisco.com
+
+
+ Michael Tuexen
+ Muenster Univ. of Applied Sciences
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Gonzalo Camarillo
+ Ericsson
+ Hirsalantie 11
+ Jorvas 02420
+ Finland
+
+ EMail: Gonzalo.Camarillo@ericsson.com
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 13]
+
+RFC 5062 SCTP Security Attacks September 2007
+
+
+Full Copyright Statement
+
+ Copyright (C) The IETF Trust (2007).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
+ THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 14]
+
diff --git a/doc/rfc6458.txt b/doc/rfc6458.txt
new file mode 100644
index 0000000..115a7fd
--- /dev/null
+++ b/doc/rfc6458.txt
@@ -0,0 +1,6443 @@
+
+
+
+
+
+
+Internet Engineering Task Force (IETF) R. Stewart
+Request for Comments: 6458 Adara Networks
+Category: Informational M. Tuexen
+ISSN: 2070-1721 Muenster Univ. of Appl. Sciences
+ K. Poon
+ Oracle Corporation
+ P. Lei
+ Cisco Systems, Inc.
+ V. Yasevich
+ HP
+ December 2011
+
+
+ Sockets API Extensions
+ for the Stream Control Transmission Protocol (SCTP)
+
+Abstract
+
+ This document describes a mapping of the Stream Control Transmission
+ Protocol (SCTP) into a sockets API. The benefits of this mapping
+ include compatibility for TCP applications, access to new SCTP
+ features, and a consolidated error and event notification scheme.
+
+Status of This Memo
+
+ This document is not an Internet Standards Track specification; it is
+ published for informational purposes.
+
+ This document is a product of the Internet Engineering Task Force
+ (IETF). It represents the consensus of the IETF community. It has
+ received public review and has been approved for publication by the
+ Internet Engineering Steering Group (IESG). Not all documents
+ approved by the IESG are a candidate for any level of Internet
+ Standard; see Section 2 of RFC 5741.
+
+ Information about the current status of this document, any errata,
+ and how to provide feedback on it may be obtained at
+ http://www.rfc-editor.org/info/rfc6458.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 1]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+Copyright Notice
+
+ Copyright (c) 2011 IETF Trust and the persons identified as the
+ document authors. All rights reserved.
+
+ This document is subject to BCP 78 and the IETF Trust's Legal
+ Provisions Relating to IETF Documents
+ (http://trustee.ietf.org/license-info) in effect on the date of
+ publication of this document. Please review these documents
+ carefully, as they describe your rights and restrictions with respect
+ to this document. Code Components extracted from this document must
+ include Simplified BSD License text as described in Section 4.e of
+ the Trust Legal Provisions and are provided without warranty as
+ described in the Simplified BSD License.
+
+ This document may contain material from IETF Documents or IETF
+ Contributions published or made publicly available before November
+ 10, 2008. The person(s) controlling the copyright in some of this
+ material may not have granted the IETF Trust the right to allow
+ modifications of such material outside the IETF Standards Process.
+ Without obtaining an adequate license from the person(s) controlling
+ the copyright in such materials, this document may not be modified
+ outside the IETF Standards Process, and derivative works of it may
+ not be created outside the IETF Standards Process, except to format
+ it for publication as an RFC or to translate it into languages other
+ than English.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 2]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+Table of Contents
+
+ 1. Introduction ....................................................6
+ 2. Data Types ......................................................8
+ 3. One-to-Many Style Interface .....................................8
+ 3.1. Basic Operation ............................................8
+ 3.1.1. socket() ............................................9
+ 3.1.2. bind() .............................................10
+ 3.1.3. listen() ...........................................11
+ 3.1.4. sendmsg() and recvmsg() ............................12
+ 3.1.5. close() ............................................14
+ 3.1.6. connect() ..........................................14
+ 3.2. Non-Blocking Mode .........................................15
+ 3.3. Special Considerations ....................................16
+ 4. One-to-One Style Interface .....................................18
+ 4.1. Basic Operation ...........................................18
+ 4.1.1. socket() ...........................................19
+ 4.1.2. bind() .............................................19
+ 4.1.3. listen() ...........................................21
+ 4.1.4. accept() ...........................................21
+ 4.1.5. connect() ..........................................22
+ 4.1.6. close() ............................................23
+ 4.1.7. shutdown() .........................................23
+ 4.1.8. sendmsg() and recvmsg() ............................24
+ 4.1.9. getpeername() ......................................24
+ 5. Data Structures ................................................25
+ 5.1. The msghdr and cmsghdr Structures .........................25
+ 5.2. Ancillary Data Considerations and Semantics ...............26
+ 5.2.1. Multiple Items and Ordering ........................27
+ 5.2.2. Accessing and Manipulating Ancillary Data ..........27
+ 5.2.3. Control Message Buffer Sizing ......................28
+ 5.3. SCTP msg_control Structures ...............................28
+ 5.3.1. SCTP Initiation Structure (SCTP_INIT) ..............29
+ 5.3.2. SCTP Header Information Structure
+ (SCTP_SNDRCV) - DEPRECATED .........................30
+ 5.3.3. Extended SCTP Header Information Structure
+ (SCTP_EXTRCV) - DEPRECATED .........................33
+ 5.3.4. SCTP Send Information Structure (SCTP_SNDINFO) .....35
+ 5.3.5. SCTP Receive Information Structure (SCTP_RCVINFO) ..37
+ 5.3.6. SCTP Next Receive Information Structure
+ (SCTP_NXTINFO) .....................................38
+ 5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO) ...39
+ 5.3.8. SCTP AUTH Information Structure (SCTP_AUTHINFO) ....40
+ 5.3.9. SCTP Destination IPv4 Address Structure
+ (SCTP_DSTADDRV4) ...................................41
+ 5.3.10. SCTP Destination IPv6 Address Structure
+ (SCTP_DSTADDRV6) ..................................41
+
+
+
+
+Stewart, et al. Informational [Page 3]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ 6. SCTP Events and Notifications ..................................41
+ 6.1. SCTP Notification Structure ...............................42
+ 6.1.1. SCTP_ASSOC_CHANGE ..................................43
+ 6.1.2. SCTP_PEER_ADDR_CHANGE ..............................45
+ 6.1.3. SCTP_REMOTE_ERROR ..................................46
+ 6.1.4. SCTP_SEND_FAILED - DEPRECATED ......................47
+ 6.1.5. SCTP_SHUTDOWN_EVENT ................................48
+ 6.1.6. SCTP_ADAPTATION_INDICATION .........................49
+ 6.1.7. SCTP_PARTIAL_DELIVERY_EVENT ........................49
+ 6.1.8. SCTP_AUTHENTICATION_EVENT ..........................50
+ 6.1.9. SCTP_SENDER_DRY_EVENT ..............................51
+ 6.1.10. SCTP_NOTIFICATIONS_STOPPED_EVENT ..................52
+ 6.1.11. SCTP_SEND_FAILED_EVENT ............................52
+ 6.2. Notification Interest Options .............................54
+ 6.2.1. SCTP_EVENTS Option - DEPRECATED ....................54
+ 6.2.2. SCTP_EVENT Option ..................................56
+ 7. Common Operations for Both Styles ..............................57
+ 7.1. send(), recv(), sendto(), and recvfrom() ..................57
+ 7.2. setsockopt() and getsockopt() .............................59
+ 7.3. read() and write() ........................................60
+ 7.4. getsockname() .............................................60
+ 7.5. Implicit Association Setup ................................61
+ 8. Socket Options .................................................61
+ 8.1. Read/Write Options ........................................63
+ 8.1.1. Retransmission Timeout Parameters (SCTP_RTOINFO) ...63
+ 8.1.2. Association Parameters (SCTP_ASSOCINFO) ............64
+ 8.1.3. Initialization Parameters (SCTP_INITMSG) ...........66
+ 8.1.4. SO_LINGER ..........................................66
+ 8.1.5. SCTP_NODELAY .......................................66
+ 8.1.6. SO_RCVBUF ..........................................67
+ 8.1.7. SO_SNDBUF ..........................................67
+ 8.1.8. Automatic Close of Associations (SCTP_AUTOCLOSE) ...67
+ 8.1.9. Set Primary Address (SCTP_PRIMARY_ADDR) ............68
+ 8.1.10. Set Adaptation Layer Indicator
+ (SCTP_ADAPTATION_LAYER) ...........................68
+ 8.1.11. Enable/Disable Message Fragmentation
+ (SCTP_DISABLE_FRAGMENTS) ..........................68
+ 8.1.12. Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) ...69
+ 8.1.13. Set Default Send Parameters
+ (SCTP_DEFAULT_SEND_PARAM) - DEPRECATED ............71
+ 8.1.14. Set Notification and Ancillary Events
+ (SCTP_EVENTS) - DEPRECATED ........................72
+ 8.1.15. Set/Clear IPv4 Mapped Addresses
+ (SCTP_I_WANT_MAPPED_V4_ADDR) ......................72
+ 8.1.16. Get or Set the Maximum Fragmentation Size
+ (SCTP_MAXSEG) .....................................72
+ 8.1.17. Get or Set the List of Supported HMAC
+ Identifiers (SCTP_HMAC_IDENT) .....................73
+
+
+
+Stewart, et al. Informational [Page 4]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ 8.1.18. Get or Set the Active Shared Key
+ (SCTP_AUTH_ACTIVE_KEY) ............................74
+ 8.1.19. Get or Set Delayed SACK Timer
+ (SCTP_DELAYED_SACK) ...............................74
+ 8.1.20. Get or Set Fragmented Interleave
+ (SCTP_FRAGMENT_INTERLEAVE) ........................75
+ 8.1.21. Set or Get the SCTP Partial Delivery Point
+ (SCTP_PARTIAL_DELIVERY_POINT) .....................77
+ 8.1.22. Set or Get the Use of Extended Receive Info
+ (SCTP_USE_EXT_RCVINFO) - DEPRECATED ...............77
+ 8.1.23. Set or Get the Auto ASCONF Flag
+ (SCTP_AUTO_ASCONF) ................................77
+ 8.1.24. Set or Get the Maximum Burst (SCTP_MAX_BURST) .....78
+ 8.1.25. Set or Get the Default Context (SCTP_CONTEXT) .....78
+ 8.1.26. Enable or Disable Explicit EOR Marking
+ (SCTP_EXPLICIT_EOR) ...............................79
+ 8.1.27. Enable SCTP Port Reusage (SCTP_REUSE_PORT) ........79
+ 8.1.28. Set Notification Event (SCTP_EVENT) ...............79
+ 8.1.29. Enable or Disable the Delivery of SCTP_RCVINFO
+ as Ancillary Data (SCTP_RECVRCVINFO) ..............79
+ 8.1.30. Enable or Disable the Delivery of SCTP_NXTINFO
+ as Ancillary Data (SCTP_RECVNXTINFO) ..............80
+ 8.1.31. Set Default Send Parameters
+ (SCTP_DEFAULT_SNDINFO) ............................80
+ 8.1.32. Set Default PR-SCTP Parameters
+ (SCTP_DEFAULT_PRINFO) .............................80
+ 8.2. Read-Only Options .........................................81
+ 8.2.1. Association Status (SCTP_STATUS) ...................81
+ 8.2.2. Peer Address Information
+ (SCTP_GET_PEER_ADDR_INFO) ..........................82
+ 8.2.3. Get the List of Chunks the Peer Requires to
+ Be Authenticated (SCTP_PEER_AUTH_CHUNKS) ...........84
+ 8.2.4. Get the List of Chunks the Local Endpoint Requires
+ to Be Authenticated (SCTP_LOCAL_AUTH_CHUNKS) .......84
+ 8.2.5. Get the Current Number of Associations
+ (SCTP_GET_ASSOC_NUMBER) ............................85
+ 8.2.6. Get the Current Identifiers of Associations
+ (SCTP_GET_ASSOC_ID_LIST) ...........................85
+ 8.3. Write-Only Options ........................................85
+ 8.3.1. Set Peer Primary Address
+ (SCTP_SET_PEER_PRIMARY_ADDR) .......................86
+ 8.3.2. Add a Chunk That Must Be Authenticated
+ (SCTP_AUTH_CHUNK) ..................................86
+ 8.3.3. Set a Shared Key (SCTP_AUTH_KEY) ...................86
+ 8.3.4. Deactivate a Shared Key
+ (SCTP_AUTH_DEACTIVATE_KEY) .........................87
+ 8.3.5. Delete a Shared Key (SCTP_AUTH_DELETE_KEY) .........88
+
+
+
+
+Stewart, et al. Informational [Page 5]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ 9. New Functions ..................................................88
+ 9.1. sctp_bindx() ..............................................88
+ 9.2. sctp_peeloff() ............................................90
+ 9.3. sctp_getpaddrs() ..........................................91
+ 9.4. sctp_freepaddrs() .........................................92
+ 9.5. sctp_getladdrs() ..........................................92
+ 9.6. sctp_freeladdrs() .........................................93
+ 9.7. sctp_sendmsg() - DEPRECATED ...............................93
+ 9.8. sctp_recvmsg() - DEPRECATED ...............................94
+ 9.9. sctp_connectx() ...........................................95
+ 9.10. sctp_send() - DEPRECATED .................................96
+ 9.11. sctp_sendx() - DEPRECATED ................................97
+ 9.12. sctp_sendv() .............................................98
+ 9.13. sctp_recvv() ............................................101
+ 10. Security Considerations ......................................103
+ 11. Acknowledgments ..............................................103
+ 12. References ...................................................104
+ 12.1. Normative References ....................................104
+ 12.2. Informative References ..................................104
+ Appendix A. Example Using One-to-One Style Sockets ...............106
+ Appendix B. Example Using One-to-Many Style Sockets ..............109
+
+1. Introduction
+
+ The sockets API has provided a standard mapping of the Internet
+ Protocol suite to many operating systems. Both TCP [RFC0793] and UDP
+ [RFC0768] have benefited from this standard representation and access
+ method across many diverse platforms. SCTP is a new protocol that
+ provides many of the characteristics of TCP but also incorporates
+ semantics more akin to UDP. This document defines a method to map
+ the existing sockets API for use with SCTP, providing both a base for
+ access to new features and compatibility so that most existing TCP
+ applications can be migrated to SCTP with few (if any) changes.
+
+ There are three basic design objectives:
+
+ 1. Maintain consistency with existing sockets APIs: We define a
+ sockets mapping for SCTP that is consistent with other sockets
+ API protocol mappings (for instance UDP, TCP, IPv4, and IPv6).
+
+ 2. Support a one-to-many style interface: This set of semantics is
+ similar to that defined for connectionless protocols, such as
+ UDP. A one-to-many style SCTP socket should be able to control
+ multiple SCTP associations. This is similar to a UDP socket,
+ which can communicate with many peer endpoints. Each of these
+ associations is assigned an association identifier so that an
+
+
+
+
+
+Stewart, et al. Informational [Page 6]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ application can use the ID to differentiate them. Note that SCTP
+ is connection-oriented in nature, and it does not support
+ broadcast or multicast communications, as UDP does.
+
+ 3. Support a one-to-one style interface: This interface supports a
+ similar semantics as sockets for connection-oriented protocols,
+ such as TCP. A one-to-one style SCTP socket should only control
+ one SCTP association. One purpose of defining this interface is
+ to allow existing applications built on other connection-oriented
+ protocols to be ported to use SCTP with very little effort.
+ Developers familiar with these semantics can easily adapt to
+ SCTP. Another purpose is to make sure that existing mechanisms
+ in most operating systems that support sockets, such as select(),
+ should continue to work with this style of socket. Extensions
+ are added to this mapping to provide mechanisms to exploit new
+ features of SCTP.
+
+ Goals 2 and 3 are not compatible, so this document defines two modes
+ of mapping, namely the one-to-many style mapping and the one-to-one
+ style mapping. These two modes share some common data structures and
+ operations, but will require the use of two different application
+ programming styles. Note that all new SCTP features can be used with
+ both styles of socket. The decision on which one to use depends
+ mainly on the nature of the applications.
+
+ A mechanism is defined to extract an SCTP association from a one-to-
+ many style socket into a one-to-one style socket.
+
+ Some of the SCTP mechanisms cannot be adequately mapped to an
+ existing socket interface. In some cases, it is more desirable to
+ have a new interface instead of using existing socket calls.
+ Section 9 of this document describes these new interfaces.
+
+ Please note that some elements of the SCTP sockets API are declared
+ as deprecated. During the evolution of this document, elements of
+ the API were introduced, implemented, and later on replaced by other
+ elements. These replaced elements are declared as deprecated, since
+ they are still available in some implementations and the replacement
+ functions are not. This applies especially to older versions of
+ operating systems supporting SCTP. New SCTP socket implementations
+ must implement at least the non-deprecated elements. Implementations
+ intending interoperability with older versions of the API should also
+ include the deprecated functions.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 7]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+2. Data Types
+
+ Whenever possible, Portable Operating System Interface (POSIX) data
+ types defined in [IEEE-1003.1-2008] are used: uintN_t means an
+ unsigned integer of exactly N bits (e.g., uint16_t). This document
+ also assumes the argument data types from POSIX when possible (e.g.,
+ the final argument to setsockopt() is a socklen_t value). Whenever
+ buffer sizes are specified, the POSIX size_t data type is used.
+
+3. One-to-Many Style Interface
+
+ In the one-to-many style interface, there is a one-to-many
+ relationship between sockets and associations.
+
+3.1. Basic Operation
+
+ A typical server in this style uses the following socket calls in
+ sequence to prepare an endpoint for servicing requests:
+
+ o socket()
+
+ o bind()
+
+ o listen()
+
+ o recvmsg()
+
+ o sendmsg()
+
+ o close()
+
+ A typical client uses the following calls in sequence to set up an
+ association with a server to request services:
+
+ o socket()
+
+ o sendmsg()
+
+ o recvmsg()
+
+ o close()
+
+ In this style, by default, all of the associations connected to the
+ endpoint are represented with a single socket. Each association is
+ assigned an association identifier (the type is sctp_assoc_t) so that
+ an application can use it to differentiate among them. In some
+ implementations, the peer endpoints' addresses can also be used for
+ this purpose. But this is not required for performance reasons. If
+
+
+
+Stewart, et al. Informational [Page 8]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ an implementation does not support using addresses to differentiate
+ between different associations, the sendto() call can only be used to
+ set up an association implicitly. It cannot be used to send data to
+ an established association, as the association identifier cannot be
+ specified.
+
+ Once an association identifier is assigned to an SCTP association,
+ that identifier will not be reused until the application explicitly
+ terminates the use of the association. The resources belonging to
+ that association will not be freed until that happens. This is
+ similar to the close() operation on a normal socket. The only
+ exception is when the SCTP_AUTOCLOSE option (Section 8.1.8) is set.
+ In this case, after the association is terminated gracefully and
+ automatically, the association identifier assigned to it can be
+ reused. All applications using this option should be aware of this
+ to avoid the possible problem of sending data to an incorrect peer
+ endpoint.
+
+ If the server or client wishes to branch an existing association off
+ to a separate socket, it is required to call sctp_peeloff() and to
+ specify the association identifier. The sctp_peeloff() call will
+ return a new one-to-one style socket that can then be used with
+ recv() and send() functions for message passing. See Section 9.2 for
+ more on branched-off associations.
+
+ Once an association is branched off to a separate socket, it becomes
+ completely separated from the original socket. All subsequent
+ control and data operations to that association must be done through
+ the new socket. For example, the close() operation on the original
+ socket will not terminate any associations that have been branched
+ off to a different socket.
+
+ One-to-many style socket calls are discussed in more detail in the
+ following subsections.
+
+3.1.1. socket()
+
+ Applications use socket() to create a socket descriptor to represent
+ an SCTP endpoint.
+
+ The function prototype is
+
+ int socket(int domain,
+ int type,
+ int protocol);
+
+ and one uses PF_INET or PF_INET6 as the domain, SOCK_SEQPACKET as the
+ type, and IPPROTO_SCTP as the protocol.
+
+
+
+Stewart, et al. Informational [Page 9]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Here, SOCK_SEQPACKET indicates the creation of a one-to-many style
+ socket.
+
+ The function returns a socket descriptor, or -1 in case of an error.
+
+ Using the PF_INET domain indicates the creation of an endpoint that
+ can use only IPv4 addresses, while PF_INET6 creates an endpoint that
+ can use both IPv6 and IPv4 addresses.
+
+3.1.2. bind()
+
+ Applications use bind() to specify with which local address and port
+ the SCTP endpoint should associate itself.
+
+ An SCTP endpoint can be associated with multiple addresses. To do
+ this, sctp_bindx() is introduced in Section 9.1 to help applications
+ do the job of associating multiple addresses. But note that an
+ endpoint can only be associated with one local port.
+
+ These addresses associated with a socket are the eligible transport
+ addresses for the endpoint to send and receive data. The endpoint
+ will also present these addresses to its peers during the association
+ initialization process; see [RFC4960].
+
+ After calling bind(), if the endpoint wishes to accept new
+ associations on the socket, it must call listen() (see
+ Section 3.1.3).
+
+ The function prototype of bind() is
+
+ int bind(int sd,
+ struct sockaddr *addr,
+ socklen_t addrlen);
+
+ and the arguments are
+
+ sd: The socket descriptor returned by socket().
+
+ addr: The address structure (struct sockaddr_in for an IPv4 address
+ or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+ addrlen: The size of the address structure.
+
+ bind() returns 0 on success and -1 in case of an error.
+
+ If sd is an IPv4 socket, the address passed must be an IPv4 address.
+ If the sd is an IPv6 socket, the address passed can either be an IPv4
+ or an IPv6 address.
+
+
+
+Stewart, et al. Informational [Page 10]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Applications cannot call bind() multiple times to associate multiple
+ addresses to an endpoint. After the first call to bind(), all
+ subsequent calls will return an error.
+
+ If the IP address part of addr is specified as a wildcard (INADDR_ANY
+ for an IPv4 address, or as IN6ADDR_ANY_INIT or in6addr_any for an
+ IPv6 address), the operating system will associate the endpoint with
+ an optimal address set of the available interfaces. If the IPv4
+ sin_port or IPv6 sin6_port is set to 0, the operating system will
+ choose an ephemeral port for the endpoint.
+
+ If bind() is not called prior to a sendmsg() call that initiates a
+ new association, the system picks an ephemeral port and will choose
+ an address set equivalent to binding with a wildcard address. One of
+ those addresses will be the primary address for the association.
+ This automatically enables the multi-homing capability of SCTP.
+
+ The completion of this bind() process does not allow the SCTP
+ endpoint to accept inbound SCTP association requests. Until a
+ listen() system call, described below, is performed on the socket,
+ the SCTP endpoint will promptly reject an inbound SCTP INIT request
+ with an SCTP ABORT.
+
+3.1.3. listen()
+
+ By default, a one-to-many style socket does not accept new
+ association requests. An application uses listen() to mark a socket
+ as being able to accept new associations.
+
+ The function prototype is
+
+ int listen(int sd,
+ int backlog);
+
+ and the arguments are
+
+ sd: The socket descriptor of the endpoint.
+
+ backlog: If backlog is non-zero, enable listening, else disable
+ listening.
+
+ listen() returns 0 on success and -1 in case of an error.
+
+ Note that one-to-many style socket consumers do not need to call
+ accept() to retrieve new associations. Calling accept() on a one-to-
+ many style socket should return EOPNOTSUPP. Rather, new associations
+ are accepted automatically, and notifications of the new associations
+ are delivered via recvmsg() with the SCTP_ASSOC_CHANGE event (if
+
+
+
+Stewart, et al. Informational [Page 11]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ these notifications are enabled). Clients will typically not call
+ listen(), so that they can be assured that only actively initiated
+ associations are possible on the socket. Server or peer-to-peer
+ sockets, on the other hand, will always accept new associations, so a
+ well-written application using server one-to-many style sockets must
+ be prepared to handle new associations from unwanted peers.
+
+ Also note that the SCTP_ASSOC_CHANGE event provides the association
+ identifier for a new association, so if applications wish to use the
+ association identifier as a parameter to other socket calls, they
+ should ensure that the SCTP_ASSOC_CHANGE event is enabled.
+
+3.1.4. sendmsg() and recvmsg()
+
+ An application uses the sendmsg() and recvmsg() calls to transmit
+ data to and receive data from its peer.
+
+ The function prototypes are
+
+ ssize_t sendmsg(int sd,
+ const struct msghdr *message,
+ int flags);
+
+ and
+
+ ssize_t recvmsg(int sd,
+ struct msghdr *message,
+ int flags);
+
+ using the following arguments:
+
+ sd: The socket descriptor of the endpoint.
+
+ message: Pointer to the msghdr structure that contains a single user
+ message and possibly some ancillary data. See Section 5 for a
+ complete description of the data structures.
+
+ flags: No new flags are defined for SCTP at this level. See
+ Section 5 for SCTP-specific flags used in the msghdr structure.
+
+ sendmsg() returns the number of bytes accepted by the kernel or -1 in
+ case of an error. recvmsg() returns the number of bytes received or
+ -1 in case of an error.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 12]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ As described in Section 5, different types of ancillary data can be
+ sent and received along with user data. When sending, the ancillary
+ data is used to specify the sent behavior, such as the SCTP stream
+ number to use. When receiving, the ancillary data is used to
+ describe the received data, such as the SCTP stream sequence number
+ of the message.
+
+ When sending user data with sendmsg(), the msg_name field in the
+ msghdr structure will be filled with one of the transport addresses
+ of the intended receiver. If there is no existing association
+ between the sender and the intended receiver, the sender's SCTP stack
+ will set up a new association and then send the user data (see
+ Section 7.5 for more on implicit association setup). If sendmsg() is
+ called with no data and there is no existing association, a new one
+ will be established. The SCTP_INIT type ancillary data can be used
+ to change some of the parameters used to set up a new association.
+ If sendmsg() is called with NULL data, and there is no existing
+ association but the SCTP_ABORT or SCTP_EOF flags are set as described
+ in Section 5.3.4, then -1 is returned and errno is set to EINVAL.
+ Sending a message using sendmsg() is atomic unless explicit end of
+ record (EOR) marking is enabled on the socket specified by sd (see
+ Section 8.1.26).
+
+ If a peer sends a SHUTDOWN, an SCTP_SHUTDOWN_EVENT notification will
+ be delivered if that notification has been enabled, and no more data
+ can be sent to that association. Any attempt to send more data will
+ cause sendmsg() to return with an ESHUTDOWN error. Note that the
+ socket is still open for reading at this point, so it is possible to
+ retrieve notifications.
+
+ When receiving a user message with recvmsg(), the msg_name field in
+ the msghdr structure will be populated with the source transport
+ address of the user data. The caller of recvmsg() can use this
+ address information to determine to which association the received
+ user message belongs. Note that if SCTP_ASSOC_CHANGE events are
+ disabled, applications must use the peer transport address provided
+ in the msg_name field by recvmsg() to perform correlation to an
+ association, since they will not have the association identifier.
+
+ If all data in a single message has been delivered, MSG_EOR will be
+ set in the msg_flags field of the msghdr structure (see Section 5.1).
+
+ If the application does not provide enough buffer space to completely
+ receive a data message, MSG_EOR will not be set in msg_flags.
+ Successive reads will consume more of the same message until the
+ entire message has been delivered, and MSG_EOR will be set.
+
+
+
+
+
+Stewart, et al. Informational [Page 13]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ If the SCTP stack is running low on buffers, it may partially deliver
+ a message. In this case, MSG_EOR will not be set, and more calls to
+ recvmsg() will be necessary to completely consume the message. Only
+ one message at a time can be partially delivered in any stream. The
+ socket option SCTP_FRAGMENT_INTERLEAVE controls various aspects of
+ what interlacing of messages occurs for both the one-to-one and the
+ one-to-many style sockets. Please consult Section 8.1.20 for further
+ details on message delivery options.
+
+3.1.5. close()
+
+ Applications use close() to perform graceful shutdown (as described
+ in Section 10.1 of [RFC4960]) on all of the associations currently
+ represented by a one-to-many style socket.
+
+ The function prototype is
+
+ int close(int sd);
+
+ and the argument is
+
+ sd: The socket descriptor of the associations to be closed.
+
+ 0 is returned on success and -1 in case of an error.
+
+ To gracefully shut down a specific association represented by the
+ one-to-many style socket, an application should use the sendmsg()
+ call and include the SCTP_EOF flag. A user may optionally terminate
+ an association non-gracefully by using sendmsg() with the SCTP_ABORT
+ flag set and possibly passing a user-specified abort code in the data
+ field. Both flags SCTP_EOF and SCTP_ABORT are passed with ancillary
+ data (see Section 5.3.4) in the sendmsg() call.
+
+ If sd in the close() call is a branched-off socket representing only
+ one association, the shutdown is performed on that association only.
+
+3.1.6. connect()
+
+ An application may use the connect() call in the one-to-many style to
+ initiate an association without sending data.
+
+ The function prototype is
+
+ int connect(int sd,
+ const struct sockaddr *nam,
+ socklen_t len);
+
+
+
+
+
+Stewart, et al. Informational [Page 14]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ and the arguments are
+
+ sd: The socket descriptor to which a new association is added.
+
+ nam: The address structure (struct sockaddr_in for an IPv4 address
+ or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+ len: The size of the address.
+
+ 0 is returned on success and -1 in case of an error.
+
+ Multiple connect() calls can be made on the same socket to create
+ multiple associations. This is different from the semantics of
+ connect() on a UDP socket.
+
+ Note that SCTP allows data exchange, similar to T/TCP [RFC1644] (made
+ Historic by [RFC6247]), during the association setup phase. If an
+ application wants to do this, it cannot use the connect() call.
+ Instead, it should use sendto() or sendmsg() to initiate an
+ association. If it uses sendto() and it wants to change the
+ initialization behavior, it needs to use the SCTP_INITMSG socket
+ option before calling sendto(). Or it can use sendmsg() with
+ SCTP_INIT type ancillary data to initiate an association without
+ calling setsockopt(). Note that the implicit setup is supported for
+ the one-to-many style sockets.
+
+ SCTP does not support half close semantics. This means that unlike
+ T/TCP, MSG_EOF should not be set in the flags parameter when calling
+ sendto() or sendmsg() when the call is used to initiate a connection.
+ MSG_EOF is not an acceptable flag with an SCTP socket.
+
+3.2. Non-Blocking Mode
+
+ Some SCTP applications may wish to avoid being blocked when calling a
+ socket interface function.
+
+ Once a bind() call and/or subsequent sctp_bindx() calls are complete
+ on a one-to-many style socket, an application may set the
+ non-blocking option via a fcntl() (such as O_NONBLOCK). After
+ setting the socket to non-blocking mode, the sendmsg() function
+ returns immediately. The success or failure of sending the data
+ message (with possible SCTP_INITMSG ancillary data) will be signaled
+ by the SCTP_ASSOC_CHANGE event with SCTP_COMM_UP or
+ SCTP_CANT_START_ASSOC. If user data could not be sent (due to an
+ SCTP_CANT_START_ASSOC), the sender will also receive an
+ SCTP_SEND_FAILED_EVENT event. Events can be received by the user
+ calling recvmsg(). A server (having called listen()) is also
+
+
+
+
+Stewart, et al. Informational [Page 15]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ notified of an association-up event via the reception of an
+ SCTP_ASSOC_CHANGE with SCTP_COMM_UP via the calling of recvmsg() and
+ possibly the reception of the first data message.
+
+ To shut down the association gracefully, the user must call sendmsg()
+ with no data and with the SCTP_EOF flag set as described in
+ Section 5.3.4. The function returns immediately, and completion of
+ the graceful shutdown is indicated by an SCTP_ASSOC_CHANGE
+ notification of type SCTP_SHUTDOWN_COMP (see Section 6.1.1). Note
+ that this can also be done using the sctp_sendv() call described in
+ Section 9.12.
+
+ It is recommended that an application use caution when using select()
+ (or poll()) for writing on a one-to-many style socket, because the
+ interpretation of select() on write is implementation specific.
+ Generally, a positive return on a select() on write would only
+ indicate that one of the associations represented by the one-to-many
+ style socket is writable. An application that writes after the
+ select() returns may still block, since the association that was
+ writable is not the destination association of the write call.
+ Likewise, select() (or poll()) for reading from a one-to-many style
+ socket will only return an indication that one of the associations
+ represented by the socket has data to be read.
+
+ An application that wishes to know that a particular association is
+ ready for reading or writing should either use the one-to-one style
+ or use the sctp_peeloff() function (see Section 9.2) to separate the
+ association of interest from the one-to-many style socket.
+
+ Note that some implementations may have an extended select call, such
+ as epoll or kqueue, that may escape this limitation and allow a
+ select on a specific association of a one-to-many style socket, but
+ this is an implementation-specific detail that a portable application
+ cannot depend on.
+
+3.3. Special Considerations
+
+ The fact that a one-to-many style socket can provide access to many
+ SCTP associations through a single socket descriptor has important
+ implications for both application programmers and system programmers
+ implementing this API. A key issue is how buffer space inside the
+ sockets layer is managed. Because this implementation detail
+ directly affects how application programmers must write their code to
+ ensure correct operation and portability, this section provides some
+ guidance to both implementers and application programmers.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 16]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ An important feature that SCTP shares with TCP is flow control.
+ Specifically, a sender may not send data faster than the receiver can
+ consume it.
+
+ For TCP, flow control is typically provided for in the sockets API as
+ follows. If the reader stops reading, the sender queues messages in
+ the socket layer until the send socket buffer is completely filled.
+ This results in a "stalled connection". Further attempts to write to
+ the socket will block or return the error EAGAIN or EWOULDBLOCK for a
+ non-blocking socket. At some point, either the connection is closed,
+ or the receiver begins to read, again freeing space in the output
+ queue.
+
+ For one-to-one style SCTP sockets (this includes sockets descriptors
+ that were separated from a one-to-many style socket with
+ sctp_peeloff()), the behavior is identical. For one-to-many style
+ SCTP sockets, there are multiple associations for a single socket,
+ which makes the situation more complicated. If the implementation
+ uses a single buffer space allocation shared by all associations, a
+ single stalled association can prevent the further sending of data on
+ all associations active on a particular one-to-many style socket.
+
+ For a blocking socket, it should be clear that a single stalled
+ association can block the entire socket. For this reason,
+ application programmers may want to use non-blocking one-to-many
+ style sockets. The application should at least be able to send
+ messages to the non-stalled associations.
+
+ But a non-blocking socket is not sufficient if the API implementer
+ has chosen a single shared buffer allocation for the socket. A
+ single stalled association would eventually cause the shared
+ allocation to fill, and it would become impossible to send even to
+ non-stalled associations.
+
+ The API implementer can solve this problem by providing each
+ association with its own allocation of outbound buffer space. Each
+ association should conceptually have as much buffer space as it would
+ have if it had its own socket. As a bonus, this simplifies the
+ implementation of sctp_peeloff().
+
+ To ensure that a given stalled association will not prevent other
+ non-stalled associations from being writable, application programmers
+ should either
+
+ o demand that the underlying implementation dedicates independent
+ buffer space reservation to each association (as suggested
+ above), or
+
+
+
+
+Stewart, et al. Informational [Page 17]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ o verify that their application-layer protocol does not permit large
+ amounts of unread data at the receiver (this is true of some
+ request-response protocols, for example), or
+
+ o use one-to-one style sockets for association, which may
+ potentially stall (either from the beginning, or by using
+ sctp_peeloff() before sending large amounts of data that may cause
+ a stalled condition).
+
+4. One-to-One Style Interface
+
+ The goal of this style is to follow as closely as possible the
+ current practice of using the sockets interface for a connection-
+ oriented protocol such as TCP. This style enables existing
+ applications using connection-oriented protocols to be ported to SCTP
+ with very little effort.
+
+ One-to-one style sockets can be connected (explicitly or implicitly)
+ at most once, similar to TCP sockets.
+
+ Note that some new SCTP features and some new SCTP socket options can
+ only be utilized through the use of sendmsg() and recvmsg() calls;
+ see Section 4.1.8.
+
+4.1. Basic Operation
+
+ A typical one-to-one style server uses the following system call
+ sequence to prepare an SCTP endpoint for servicing requests:
+
+ o socket()
+
+ o bind()
+
+ o listen()
+
+ o accept()
+
+ The accept() call blocks until a new association is set up. It
+ returns with a new socket descriptor. The server then uses the new
+ socket descriptor to communicate with the client, using recv() and
+ send() calls to get requests and send back responses.
+
+ Then it calls
+
+ o close()
+
+ to terminate the association.
+
+
+
+
+Stewart, et al. Informational [Page 18]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ A typical client uses the following system call sequence to set up an
+ association with a server to request services:
+
+ o socket()
+
+ o connect()
+
+ After returning from the connect() call, the client uses send()/
+ sendmsg() and recv()/recvmsg() calls to send out requests and receive
+ responses from the server.
+
+ The client calls
+
+ o close()
+
+ to terminate this association when done.
+
+4.1.1. socket()
+
+ Applications call socket() to create a socket descriptor to represent
+ an SCTP endpoint.
+
+ The function prototype is
+
+ int socket(int domain,
+ int type,
+ int protocol);
+
+ and one uses PF_INET or PF_INET6 as the domain, SOCK_STREAM as the
+ type, and IPPROTO_SCTP as the protocol.
+
+ Here, SOCK_STREAM indicates the creation of a one-to-one style
+ socket.
+
+ Using the PF_INET domain indicates the creation of an endpoint that
+ can use only IPv4 addresses, while PF_INET6 creates an endpoint that
+ can use both IPv6 and IPv4 addresses.
+
+4.1.2. bind()
+
+ Applications use bind() to specify with which local address and port
+ the SCTP endpoint should associate itself.
+
+ An SCTP endpoint can be associated with multiple addresses. To do
+ this, sctp_bindx() is introduced in Section 9.1 to help applications
+ do the job of associating multiple addresses. But note that an
+ endpoint can only be associated with one local port.
+
+
+
+
+Stewart, et al. Informational [Page 19]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ These addresses associated with a socket are the eligible transport
+ addresses for the endpoint to send and receive data. The endpoint
+ will also present these addresses to its peers during the association
+ initialization process; see [RFC4960].
+
+ The function prototype of bind() is
+
+ int bind(int sd,
+ struct sockaddr *addr,
+ socklen_t addrlen);
+
+ and the arguments are
+
+ sd: The socket descriptor returned by socket().
+
+ addr: The address structure (struct sockaddr_in for an IPv4 address
+ or struct sockaddr_in6 for an IPv6 address; see [RFC3493]).
+
+ addrlen: The size of the address structure.
+
+ If sd is an IPv4 socket, the address passed must be an IPv4 address.
+ If sd is an IPv6 socket, the address passed can either be an IPv4 or
+ an IPv6 address.
+
+ Applications cannot call bind() multiple times to associate multiple
+ addresses to the endpoint. After the first call to bind(), all
+ subsequent calls will return an error.
+
+ If the IP address part of addr is specified as a wildcard (INADDR_ANY
+ for an IPv4 address, or as IN6ADDR_ANY_INIT or in6addr_any for an
+ IPv6 address), the operating system will associate the endpoint with
+ an optimal address set of the available interfaces. If the IPv4
+ sin_port or IPv6 sin6_port is set to 0, the operating system will
+ choose an ephemeral port for the endpoint.
+
+ If bind() is not called prior to the connect() call, the system picks
+ an ephemeral port and will choose an address set equivalent to
+ binding with a wildcard address. One of these addresses will be the
+ primary address for the association. This automatically enables the
+ multi-homing capability of SCTP.
+
+ The completion of this bind() process does not allow the SCTP
+ endpoint to accept inbound SCTP association requests. Until a
+ listen() system call, described below, is performed on the socket,
+ the SCTP endpoint will promptly reject an inbound SCTP INIT request
+ with an SCTP ABORT.
+
+
+
+
+
+Stewart, et al. Informational [Page 20]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+4.1.3. listen()
+
+ Applications use listen() to allow the SCTP endpoint to accept
+ inbound associations.
+
+ The function prototype is
+
+ int listen(int sd,
+ int backlog);
+
+ and the arguments are
+
+ sd: The socket descriptor of the SCTP endpoint.
+
+ backlog: Specifies the max number of outstanding associations
+ allowed in the socket's accept queue. These are the associations
+ that have finished the four-way initiation handshake (see
+ Section 5 of [RFC4960]) and are in the ESTABLISHED state. Note
+ that a backlog of '0' indicates that the caller no longer wishes
+ to receive new associations.
+
+ listen() returns 0 on success and -1 in case of an error.
+
+4.1.4. accept()
+
+ Applications use the accept() call to remove an established SCTP
+ association from the accept queue of the endpoint. A new socket
+ descriptor will be returned from accept() to represent the newly
+ formed association.
+
+ The function prototype is
+
+ int accept(int sd,
+ struct sockaddr *addr,
+ socklen_t *addrlen);
+
+ and the arguments are
+
+ sd: The listening socket descriptor.
+
+ addr: On return, addr (struct sockaddr_in for an IPv4 address or
+ struct sockaddr_in6 for an IPv6 address; see [RFC3493]) will
+ contain the primary address of the peer endpoint.
+
+ addrlen: On return, addrlen will contain the size of addr.
+
+ The function returns the socket descriptor for the newly formed
+ association on success and -1 in case of an error.
+
+
+
+Stewart, et al. Informational [Page 21]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+4.1.5. connect()
+
+ Applications use connect() to initiate an association to a peer.
+
+ The function prototype is
+
+ int connect(int sd,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
+
+ and the arguments are
+
+ sd: The socket descriptor of the endpoint.
+
+ addr: The peer's (struct sockaddr_in for an IPv4 address or struct
+ sockaddr_in6 for an IPv6 address; see [RFC3493]) address.
+
+ addrlen: The size of the address.
+
+ connect() returns 0 on success and -1 on error.
+
+ This operation corresponds to the ASSOCIATE primitive described in
+ Section 10.1 of [RFC4960].
+
+ The number of outbound streams the new association has is stack
+ dependent. Before connecting, applications can use the SCTP_INITMSG
+ option described in Section 8.1.3 to change the number of outbound
+ streams.
+
+ If bind() is not called prior to the connect() call, the system picks
+ an ephemeral port and will choose an address set equivalent to
+ binding with INADDR_ANY and IN6ADDR_ANY_INIT for IPv4 and IPv6
+ sockets, respectively. One of the addresses will be the primary
+ address for the association. This automatically enables the
+ multi-homing capability of SCTP.
+
+ Note that SCTP allows data exchange, similar to T/TCP [RFC1644] (made
+ Historic by [RFC6247]), during the association setup phase. If an
+ application wants to do this, it cannot use the connect() call.
+ Instead, it should use sendto() or sendmsg() to initiate an
+ association. If it uses sendto() and it wants to change the
+ initialization behavior, it needs to use the SCTP_INITMSG socket
+ option before calling sendto(). Or it can use sendmsg() with
+ SCTP_INIT type ancillary data to initiate an association without
+ calling setsockopt(). Note that the implicit setup is supported for
+ the one-to-one style sockets.
+
+
+
+
+
+Stewart, et al. Informational [Page 22]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SCTP does not support half close semantics. This means that unlike
+ T/TCP, MSG_EOF should not be set in the flags parameter when calling
+ sendto() or sendmsg() when the call is used to initiate a connection.
+ MSG_EOF is not an acceptable flag with an SCTP socket.
+
+4.1.6. close()
+
+ Applications use close() to gracefully close down an association.
+
+ The function prototype is
+
+ int close(int sd);
+
+ and the argument is
+
+ sd: The socket descriptor of the association to be closed.
+
+ close() returns 0 on success and -1 in case of an error.
+
+ After an application calls close() on a socket descriptor, no further
+ socket operations will succeed on that descriptor.
+
+4.1.7. shutdown()
+
+ SCTP differs from TCP in that it does not have half close semantics.
+ Hence, the shutdown() call for SCTP is an approximation of the TCP
+ shutdown() call, and solves some different problems. Full TCP
+ compatibility is not provided, so developers porting TCP applications
+ to SCTP may need to recode sections that use shutdown(). (Note that
+ it is possible to achieve the same results as half close in SCTP
+ using SCTP streams.)
+
+ The function prototype is
+
+ int shutdown(int sd,
+ int how);
+
+ and the arguments are
+
+ sd: The socket descriptor of the association to be closed.
+
+ how: Specifies the type of shutdown. The values are as follows:
+
+ SHUT_RD: Disables further receive operations. No SCTP protocol
+ action is taken.
+
+ SHUT_WR: Disables further send operations, and initiates the SCTP
+ shutdown sequence.
+
+
+
+Stewart, et al. Informational [Page 23]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SHUT_RDWR: Disables further send and receive operations, and
+ initiates the SCTP shutdown sequence.
+
+ shutdown() returns 0 on success and -1 in case of an error.
+
+ The major difference between SCTP and TCP shutdown() is that SCTP
+ SHUT_WR initiates immediate and full protocol shutdown, whereas TCP
+ SHUT_WR causes TCP to go into the half close state. SHUT_RD behaves
+ the same for SCTP as for TCP. The purpose of SCTP SHUT_WR is to
+ close the SCTP association while still leaving the socket descriptor
+ open. This allows the caller to receive back any data that SCTP is
+ unable to deliver (see Section 6.1.4 for more information) and
+ receive event notifications.
+
+ To perform the ABORT operation described in Section 10.1 of
+ [RFC4960], an application can use the socket option SO_LINGER.
+ SO_LINGER is described in Section 8.1.4.
+
+4.1.8. sendmsg() and recvmsg()
+
+ With a one-to-one style socket, the application can also use
+ sendmsg() and recvmsg() to transmit data to and receive data from its
+ peer. The semantics is similar to those used in the one-to-many
+ style (see Section 3.1.4), with the following differences:
+
+ 1. When sending, the msg_name field in the msghdr is not used to
+ specify the intended receiver; rather, it is used to indicate a
+ preferred peer address if the sender wishes to discourage the
+ stack from sending the message to the primary address of the
+ receiver. If the socket is connected and the transport address
+ given is not part of the current association, the data will not
+ be sent, and an SCTP_SEND_FAILED_EVENT event will be delivered to
+ the application if send failure events are enabled.
+
+ 2. Using sendmsg() on a non-connected one-to-one style socket for
+ implicit connection setup may or may not work, depending on the
+ SCTP implementation.
+
+4.1.9. getpeername()
+
+ Applications use getpeername() to retrieve the primary socket address
+ of the peer. This call is for TCP compatibility and is not
+ multi-homed. It may not work with one-to-many style sockets,
+ depending on the implementation. See Section 9.3 for a multi-homed
+ style version of the call.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 24]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The function prototype is
+
+ int getpeername(int sd,
+ struct sockaddr *address,
+ socklen_t *len);
+
+ and the arguments are
+
+ sd: The socket descriptor to be queried.
+
+ address: On return, the peer primary address is stored in this
+ buffer. If the socket is an IPv4 socket, the address will be
+ IPv4. If the socket is an IPv6 socket, the address will be either
+ an IPv6 or IPv4 address.
+
+ len: The caller should set the length of address here. On return,
+ this is set to the length of the returned address.
+
+ getpeername() returns 0 on success and -1 in case of an error.
+
+ If the actual length of the address is greater than the length of the
+ supplied sockaddr structure, the stored address will be truncated.
+
+5. Data Structures
+
+ This section discusses important data structures that are specific to
+ SCTP and are used with sendmsg() and recvmsg() calls to control SCTP
+ endpoint operations and to access ancillary information and
+ notifications.
+
+5.1. The msghdr and cmsghdr Structures
+
+ The msghdr structure used in the sendmsg() and recvmsg() calls, as
+ well as the ancillary data carried in the structure, is the key for
+ the application to set and get various control information from the
+ SCTP endpoint.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 25]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The msghdr and the related cmsghdr structures are defined and
+ discussed in detail in [RFC3542]. They are defined as
+
+ struct msghdr {
+ void *msg_name; /* ptr to socket address structure */
+ socklen_t msg_namelen; /* size of socket address structure */
+ struct iovec *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ void *msg_control; /* ancillary data */
+ socklen_t msg_controllen; /* ancillary data buffer length */
+ int msg_flags; /* flags on received message */
+ };
+
+ struct cmsghdr {
+ socklen_t cmsg_len; /* # bytes, including this header */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+ /* followed by unsigned char cmsg_data[]; */
+ };
+
+ In the msghdr structure, the usage of msg_name has been discussed in
+ previous sections (see Sections 3.1.4 and 4.1.8).
+
+ The scatter/gather buffers, or I/O vectors (pointed to by the msg_iov
+ field) are treated by SCTP as a single user message for both
+ sendmsg() and recvmsg().
+
+ The SCTP stack uses the ancillary data (msg_control field) to
+ communicate the attributes, such as SCTP_RCVINFO, of the message
+ stored in msg_iov to the socket endpoint. The different ancillary
+ data types are described in Section 5.3.
+
+ The msg_flags are not used when sending a message with sendmsg().
+
+ If a notification has arrived, recvmsg() will return the notification
+ in the msg_iov field and set the MSG_NOTIFICATION flag in msg_flags.
+ If the MSG_NOTIFICATION flag is not set, recvmsg() will return data.
+ See Section 6 for more information about notifications.
+
+ If all portions of a data frame or notification have been read,
+ recvmsg() will return with MSG_EOR set in msg_flags.
+
+5.2. Ancillary Data Considerations and Semantics
+
+ Programming with ancillary socket data (msg_control) contains some
+ subtleties and pitfalls, which are discussed below.
+
+
+
+
+
+Stewart, et al. Informational [Page 26]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+5.2.1. Multiple Items and Ordering
+
+ Multiple ancillary data items may be included in any call to
+ sendmsg() or recvmsg(); these may include multiple SCTP items,
+ non-SCTP items (such as IP-level items), or both.
+
+ The ordering of ancillary data items (either by SCTP or another
+ protocol) is not significant and is implementation dependent, so
+ applications must not depend on any ordering.
+
+ SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO type ancillary data always
+ corresponds to the data in the msghdr's msg_iov member. There can be
+ only one such type of ancillary data for each sendmsg() or recvmsg()
+ call.
+
+5.2.2. Accessing and Manipulating Ancillary Data
+
+ Applications can infer the presence of data or ancillary data by
+ examining the msg_iovlen and msg_controllen msghdr members,
+ respectively.
+
+ Implementations may have different padding requirements for ancillary
+ data, so portable applications should make use of the macros
+ CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_SPACE, and CMSG_LEN. See
+ [RFC3542] and the SCTP implementation's documentation for more
+ information. The following is an example, from [RFC3542],
+ demonstrating the use of these macros to access ancillary data:
+
+ struct msghdr msg;
+ struct cmsghdr *cmsgptr;
+
+ /* fill in msg */
+
+ /* call recvmsg() */
+
+ for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
+ cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+ if (cmsgptr->cmsg_len == 0) {
+ /* Error handling */
+ break;
+ }
+ if (cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ... ) {
+ u_char *ptr;
+
+ ptr = CMSG_DATA(cmsgptr);
+ /* process data pointed to by ptr */
+ }
+ }
+
+
+
+Stewart, et al. Informational [Page 27]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+5.2.3. Control Message Buffer Sizing
+
+ The information conveyed via SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO
+ ancillary data will often be fundamental to the correct and sane
+ operation of the sockets application. This is particularly true for
+ one-to-many style sockets, but also for one-to-one style sockets.
+ For example, if an application needs to send and receive data on
+ different SCTP streams, SCTP_SNDRCV/SCTP_SNDINFO/SCTP_RCVINFO
+ ancillary data is indispensable.
+
+ Given that some ancillary data is critical, and that multiple
+ ancillary data items may appear in any order, applications should be
+ carefully written to always provide a large enough buffer to contain
+ all possible ancillary data that can be presented by recvmsg(). If
+ the buffer is too small, and crucial data is truncated, it may pose a
+ fatal error condition.
+
+ Thus, it is essential that applications be able to deterministically
+ calculate the maximum required buffer size to pass to recvmsg(). One
+ constraint imposed on this specification that makes this possible is
+ that all ancillary data definitions are of a fixed length. One way
+ to calculate the maximum required buffer size might be to take the
+ sum of the sizes of all enabled ancillary data item structures, as
+ calculated by CMSG_SPACE. For example, if we enabled
+ SCTP_SNDRCV_INFO and IPV6_RECVPKTINFO [RFC3542], we would calculate
+ and allocate the buffer size as follows:
+
+ size_t total;
+ void *buf;
+
+ total = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)) +
+ CMSG_SPACE(sizeof(struct in6_pktinfo));
+
+ buf = malloc(total);
+
+ We could then use this buffer (buf) for msg_control on each call to
+ recvmsg() and be assured that we would not lose any ancillary data to
+ truncation.
+
+5.3. SCTP msg_control Structures
+
+ A key element of all SCTP-specific socket extensions is the use of
+ ancillary data to specify and access SCTP-specific data via the
+ msghdr structure's msg_control member used in sendmsg() and
+ recvmsg(). Fine-grained control over initialization and sending
+ parameters are handled with ancillary data.
+
+
+
+
+
+Stewart, et al. Informational [Page 28]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Each ancillary data item is preceded by a struct cmsghdr (see
+ Section 5.1), which defines the function and purpose of the data
+ contained in the cmsg_data[] member.
+
+ By default, on either style of socket, SCTP will pass no ancillary
+ data. Specific ancillary data items can be enabled with socket
+ options defined for SCTP; see Section 6.2.
+
+ Note that all ancillary types are of fixed length; see Section 5.2
+ for further discussion on this. These data structures use struct
+ sockaddr_storage (defined in [RFC3493]) as a portable, fixed-length
+ address format.
+
+ Other protocols may also provide ancillary data to the socket layer
+ consumer. These ancillary data items from other protocols may
+ intermingle with SCTP data. For example, the IPv6 sockets API
+ definitions ([RFC3542] and [RFC3493]) define a number of ancillary
+ data items. If a sockets API consumer enables delivery of both SCTP
+ and IPv6 ancillary data, they both may appear in the same msg_control
+ buffer in any order. An application may thus need to handle other
+ types of ancillary data besides those passed by SCTP.
+
+ The sockets application must provide a buffer large enough to
+ accommodate all ancillary data provided via recvmsg(). If the buffer
+ is not large enough, the ancillary data will be truncated and the
+ msghdr's msg_flags will include MSG_CTRUNC.
+
+5.3.1. SCTP Initiation Structure (SCTP_INIT)
+
+ This cmsghdr structure provides information for initializing new SCTP
+ associations with sendmsg(). The SCTP_INITMSG socket option uses
+ this same data structure. This structure is not used for recvmsg().
+
+ +--------------+-----------+---------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+-----------+---------------------+
+ | IPPROTO_SCTP | SCTP_INIT | struct sctp_initmsg |
+ +--------------+-----------+---------------------+
+
+ The sctp_initmsg structure is defined below:
+
+ struct sctp_initmsg {
+ uint16_t sinit_num_ostreams;
+ uint16_t sinit_max_instreams;
+ uint16_t sinit_max_attempts;
+ uint16_t sinit_max_init_timeo;
+ };
+
+
+
+
+Stewart, et al. Informational [Page 29]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sinit_num_ostreams: This is an integer representing the number of
+ streams to which the application wishes to be able to send. This
+ number is confirmed in the SCTP_COMM_UP notification and must be
+ verified, since it is a negotiated number with the remote
+ endpoint. The default value of 0 indicates the use of the
+ endpoint's default value.
+
+ sinit_max_instreams: This value represents the maximum number of
+ inbound streams the application is prepared to support. This
+ value is bounded by the actual implementation. In other words,
+ the user may be able to support more streams than the operating
+ system. In such a case, the operating-system limit overrides the
+ value requested by the user. The default value of 0 indicates the
+ use of the endpoint's default value.
+
+ sinit_max_attempts: This integer specifies how many attempts the
+ SCTP endpoint should make at resending the INIT. This value
+ overrides the system SCTP 'Max.Init.Retransmits' value. The
+ default value of 0 indicates the use of the endpoint's default
+ value. This is normally set to the system's default
+ 'Max.Init.Retransmit' value.
+
+ sinit_max_init_timeo: This value represents the largest timeout or
+ retransmission timeout (RTO) value (in milliseconds) to use in
+ attempting an INIT. Normally, the 'RTO.Max' is used to limit the
+ doubling of the RTO upon timeout. For the INIT message, this
+ value may override 'RTO.Max'. This value must not influence
+ 'RTO.Max' during data transmission and is only used to bound the
+ initial setup time. A default value of 0 indicates the use of the
+ endpoint's default value. This is normally set to the system's
+ 'RTO.Max' value (60 seconds).
+
+5.3.2. SCTP Header Information Structure (SCTP_SNDRCV) - DEPRECATED
+
+ This cmsghdr structure specifies SCTP options for sendmsg() and
+ describes SCTP header information about a received message through
+ recvmsg(). This structure mixes the send and receive path.
+ SCTP_SNDINFO (described in Section 5.3.4) and SCTP_RCVINFO (described
+ in Section 5.3.5) split this information. These structures should be
+ used, when possible, since SCTP_SNDRCV is deprecated.
+
+ +--------------+-------------+------------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+-------------+------------------------+
+ | IPPROTO_SCTP | SCTP_SNDRCV | struct sctp_sndrcvinfo |
+ +--------------+-------------+------------------------+
+
+
+
+
+
+Stewart, et al. Informational [Page 30]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The sctp_sndrcvinfo structure is defined below:
+
+ struct sctp_sndrcvinfo {
+ uint16_t sinfo_stream;
+ uint16_t sinfo_ssn;
+ uint16_t sinfo_flags;
+ uint32_t sinfo_ppid;
+ uint32_t sinfo_context;
+ uint32_t sinfo_timetolive;
+ uint32_t sinfo_tsn;
+ uint32_t sinfo_cumtsn;
+ sctp_assoc_t sinfo_assoc_id;
+ };
+
+ sinfo_stream: For recvmsg(), the SCTP stack places the message's
+ stream number in this value. For sendmsg(), this value holds the
+ stream number to which the application wishes to send this
+ message. If a sender specifies an invalid stream number, an error
+ indication is returned and the call fails.
+
+ sinfo_ssn: For recvmsg(), this value contains the stream sequence
+ number that the remote endpoint placed in the DATA chunk. For
+ fragmented messages, this is the same number for all deliveries of
+ the message (if more than one recvmsg() is needed to read the
+ message). The sendmsg() call will ignore this parameter.
+
+ sinfo_flags: This field may contain any of the following flags and
+ is composed of a bitwise OR of these values.
+
+ recvmsg() flags:
+
+ SCTP_UNORDERED: This flag is present when the message was sent
+ unordered.
+
+ sendmsg() flags:
+
+ SCTP_UNORDERED: This flag requests the unordered delivery of
+ the message. If this flag is clear, the datagram is
+ considered an ordered send.
+
+ SCTP_ADDR_OVER: This flag, for a one-to-many style socket,
+ requests that the SCTP stack override the primary
+ destination address with the address found with the sendto/
+ sendmsg call.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 31]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SCTP_ABORT: Setting this flag causes the specified association
+ to abort by sending an ABORT message to the peer. The ABORT
+ chunk will contain an error cause of 'User Initiated Abort'
+ with cause code 12. The cause-specific information of this
+ error cause is provided in msg_iov.
+
+ SCTP_EOF: Setting this flag invokes the SCTP graceful shutdown
+ procedure on the specified association. Graceful shutdown
+ assures that all data queued by both endpoints is
+ successfully transmitted before closing the association.
+
+ SCTP_SENDALL: This flag, if set, will cause a one-to-many
+ style socket to send the message to all associations that
+ are currently established on this socket. For the one-to-
+ one style socket, this flag has no effect.
+
+ sinfo_ppid: This value in sendmsg() is an unsigned integer that is
+ passed to the remote end in each user message. In recvmsg(), this
+ value is the same information that was passed by the upper layer
+ in the peer application. Please note that the SCTP stack performs
+ no byte order modification of this field. For example, if the
+ DATA chunk has to contain a given value in network byte order, the
+ SCTP user has to perform the htonl() computation.
+
+ sinfo_context: This value is an opaque 32-bit context datum that is
+ used in the sendmsg() function. This value is passed back to the
+ upper layer if an error occurs on the send of a message and is
+ retrieved with each undelivered message.
+
+ sinfo_timetolive: For the sending side, this field contains the
+ message's time to live, in milliseconds. The sending side will
+ expire the message within the specified time period if the message
+ has not been sent to the peer within this time period. This value
+ will override any default value set using any socket option. Also
+ note that the value of 0 is special in that it indicates no
+ timeout should occur on this message.
+
+ sinfo_tsn: For the receiving side, this field holds a Transmission
+ Sequence Number (TSN) that was assigned to one of the SCTP DATA
+ chunks. For the sending side, it is ignored.
+
+ sinfo_cumtsn: This field will hold the current cumulative TSN as
+ known by the underlying SCTP layer. Note that this field is
+ ignored when sending.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 32]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sinfo_assoc_id: The association handle field, sinfo_assoc_id, holds
+ the identifier for the association announced in the SCTP_COMM_UP
+ notification. All notifications for a given association have the
+ same identifier. This field is ignored for one-to-one style
+ sockets.
+
+ An sctp_sndrcvinfo item always corresponds to the data in msg_iov.
+
+5.3.3. Extended SCTP Header Information Structure (SCTP_EXTRCV) -
+ DEPRECATED
+
+ This cmsghdr structure specifies SCTP options for SCTP header
+ information about a received message via recvmsg(). Note that this
+ structure is an extended version of SCTP_SNDRCV (see Section 5.3.2)
+ and will only be received if the user has set the socket option
+ SCTP_USE_EXT_RCVINFO (see Section 8.1.22) to true in addition to any
+ event subscription needed to receive ancillary data. Note that data
+ in the next message is not valid unless the current message is
+ completely read, i.e., unless the MSG_EOR is set; in other words, if
+ the application has more data to read from the current message, then
+ no next-message information will be available.
+
+ SCTP_NXTINFO (described in Section 5.3.6) should be used when
+ possible, since SCTP_EXTRCV is considered deprecated.
+
+ +--------------+-------------+------------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+-------------+------------------------+
+ | IPPROTO_SCTP | SCTP_EXTRCV | struct sctp_extrcvinfo |
+ +--------------+-------------+------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 33]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The sctp_extrcvinfo structure is defined below:
+
+ struct sctp_extrcvinfo {
+ uint16_t sinfo_stream;
+ uint16_t sinfo_ssn;
+ uint16_t sinfo_flags;
+ uint32_t sinfo_ppid;
+ uint32_t sinfo_context;
+ uint32_t sinfo_pr_value;
+ uint32_t sinfo_tsn;
+ uint32_t sinfo_cumtsn;
+ uint16_t serinfo_next_flags;
+ uint16_t serinfo_next_stream;
+ uint32_t serinfo_next_aid;
+ uint32_t serinfo_next_length;
+ uint32_t serinfo_next_ppid;
+ sctp_assoc_t sinfo_assoc_id;
+ };
+
+ sinfo_*: Please see Section 5.3.2 for details for these fields.
+
+ serinfo_next_flags: This bitmask will hold one or more of the
+ following values:
+
+ SCTP_NEXT_MSG_AVAIL: This bit, when set to 1, indicates that
+ next-message information is available; i.e., next_stream,
+ next_aid, next_length, and next_ppid fields all have valid
+ values. If this bit is set to 0, then these fields are not
+ valid and should be ignored.
+
+ SCTP_NEXT_MSG_ISCOMPLETE: This bit, when set, indicates that the
+ next message is completely in the receive buffer. The
+ next_length field thus contains the entire message size. If
+ this flag is set to 0, then the next_length field only contains
+ part of the message size, since the message is still being
+ received (it is being partially delivered).
+
+ SCTP_NEXT_MSG_IS_UNORDERED: This bit, when set, indicates that
+ the next message to be received was sent by the peer as
+ unordered. If this bit is not set (i.e., the bit is 0) the
+ next message to be read is an ordered message in the stream
+ specified.
+
+ SCTP_NEXT_MSG_IS_NOTIFICATION: This bit, when set, indicates that
+ the next message to be received is not a message from the peer,
+ but instead is a MSG_NOTIFICATION from the local SCTP stack.
+
+
+
+
+
+Stewart, et al. Informational [Page 34]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ serinfo_next_stream: This value, when valid (see
+ serinfo_next_flags), contains the next stream number that will be
+ received on a subsequent call to one of the receive message
+ functions.
+
+ serinfo_next_aid: This value, when valid (see serinfo_next_flags),
+ contains the next association identifier that will be received on
+ a subsequent call to one of the receive message functions.
+
+ serinfo_next_length: This value, when valid (see
+ serinfo_next_flags), contains the length of the next message that
+ will be received on a subsequent call to one of the receive
+ message functions. Note that this length may be a partial length,
+ depending on the settings of next_flags.
+
+ serinfo_next_ppid: This value, when valid (see serinfo_next_flags),
+ contains the ppid of the next message that will be received on a
+ subsequent call to one of the receive message functions.
+
+5.3.4. SCTP Send Information Structure (SCTP_SNDINFO)
+
+ This cmsghdr structure specifies SCTP options for sendmsg().
+
+ +--------------+--------------+---------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+--------------+---------------------+
+ | IPPROTO_SCTP | SCTP_SNDINFO | struct sctp_sndinfo |
+ +--------------+--------------+---------------------+
+
+ The sctp_sndinfo structure is defined below:
+
+ struct sctp_sndinfo {
+ uint16_t snd_sid;
+ uint16_t snd_flags;
+ uint32_t snd_ppid;
+ uint32_t snd_context;
+ sctp_assoc_t snd_assoc_id;
+ };
+
+ snd_sid: This value holds the stream number to which the application
+ wishes to send this message. If a sender specifies an invalid
+ stream number, an error indication is returned and the call fails.
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 35]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ snd_flags: This field may contain any of the following flags and is
+ composed of a bitwise OR of these values.
+
+ SCTP_UNORDERED: This flag requests the unordered delivery of the
+ message. If this flag is clear, the datagram is considered an
+ ordered send.
+
+ SCTP_ADDR_OVER: This flag, for a one-to-many style socket,
+ requests that the SCTP stack override the primary destination
+ address with the address found with the sendto()/sendmsg call.
+
+ SCTP_ABORT: Setting this flag causes the specified association to
+ abort by sending an ABORT message to the peer. The ABORT chunk
+ will contain an error cause of 'User Initiated Abort' with
+ cause code 12. The cause-specific information of this error
+ cause is provided in msg_iov.
+
+ SCTP_EOF: Setting this flag invokes the SCTP graceful shutdown
+ procedures on the specified association. Graceful shutdown
+ assures that all data queued by both endpoints is successfully
+ transmitted before closing the association.
+
+ SCTP_SENDALL: This flag, if set, will cause a one-to-many style
+ socket to send the message to all associations that are
+ currently established on this socket. For the one-to-one style
+ socket, this flag has no effect.
+
+ snd_ppid: This value in sendmsg() is an unsigned integer that is
+ passed to the remote end in each user message. Please note that
+ the SCTP stack performs no byte order modification of this field.
+ For example, if the DATA chunk has to contain a given value in
+ network byte order, the SCTP user has to perform the htonl()
+ computation.
+
+ snd_context: This value is an opaque 32-bit context datum that is
+ used in the sendmsg() function. This value is passed back to the
+ upper layer if an error occurs on the send of a message and is
+ retrieved with each undelivered message.
+
+ snd_assoc_id: The association handle field, sinfo_assoc_id, holds
+ the identifier for the association announced in the SCTP_COMM_UP
+ notification. All notifications for a given association have the
+ same identifier. This field is ignored for one-to-one style
+ sockets.
+
+ An sctp_sndinfo item always corresponds to the data in msg_iov.
+
+
+
+
+
+Stewart, et al. Informational [Page 36]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+5.3.5. SCTP Receive Information Structure (SCTP_RCVINFO)
+
+ This cmsghdr structure describes SCTP receive information about a
+ received message through recvmsg().
+
+ To enable the delivery of this information, an application must use
+ the SCTP_RECVRCVINFO socket option (see Section 8.1.29).
+
+ +--------------+--------------+---------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+--------------+---------------------+
+ | IPPROTO_SCTP | SCTP_RCVINFO | struct sctp_rcvinfo |
+ +--------------+--------------+---------------------+
+
+ The sctp_rcvinfo structure is defined below:
+
+ struct sctp_rcvinfo {
+ uint16_t rcv_sid;
+ uint16_t rcv_ssn;
+ uint16_t rcv_flags;
+ uint32_t rcv_ppid;
+ uint32_t rcv_tsn;
+ uint32_t rcv_cumtsn;
+ uint32_t rcv_context;
+ sctp_assoc_t rcv_assoc_id;
+ };
+
+ rcv_sid: The SCTP stack places the message's stream number in this
+ value.
+
+ rcv_ssn: This value contains the stream sequence number that the
+ remote endpoint placed in the DATA chunk. For fragmented
+ messages, this is the same number for all deliveries of the
+ message (if more than one recvmsg() is needed to read the
+ message).
+
+ rcv_flags: This field may contain any of the following flags and is
+ composed of a bitwise OR of these values.
+
+ SCTP_UNORDERED: This flag is present when the message was sent
+ unordered.
+
+ rcv_ppid: This value is the same information that was passed by the
+ upper layer in the peer application. Please note that the SCTP
+ stack performs no byte order modification of this field. For
+ example, if the DATA chunk has to contain a given value in network
+ byte order, the SCTP user has to perform the ntohl() computation.
+
+
+
+
+Stewart, et al. Informational [Page 37]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ rcv_tsn: This field holds a TSN that was assigned to one of the SCTP
+ DATA chunks.
+
+ rcv_cumtsn: This field will hold the current cumulative TSN as known
+ by the underlying SCTP layer.
+
+ rcv_context: This value is an opaque 32-bit context datum that was
+ set by the user with the SCTP_CONTEXT socket option. This value
+ is passed back to the upper layer if an error occurs on the send
+ of a message and is retrieved with each undelivered message.
+
+ rcv_assoc_id: The association handle field, sinfo_assoc_id, holds
+ the identifier for the association announced in the SCTP_COMM_UP
+ notification. All notifications for a given association have the
+ same identifier. This field is ignored for one-to-one style
+ sockets.
+
+ An sctp_rcvinfo item always corresponds to the data in msg_iov.
+
+5.3.6. SCTP Next Receive Information Structure (SCTP_NXTINFO)
+
+ This cmsghdr structure describes SCTP receive information of the next
+ message that will be delivered through recvmsg() if this information
+ is already available when delivering the current message.
+
+ To enable the delivery of this information, an application must use
+ the SCTP_RECVNXTINFO socket option (see Section 8.1.30).
+
+ +--------------+--------------+---------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+--------------+---------------------+
+ | IPPROTO_SCTP | SCTP_NXTINFO | struct sctp_nxtinfo |
+ +--------------+--------------+---------------------+
+
+ The sctp_nxtinfo structure is defined below:
+
+ struct sctp_nxtinfo {
+ uint16_t nxt_sid;
+ uint16_t nxt_flags;
+ uint32_t nxt_ppid;
+ uint32_t nxt_length;
+ sctp_assoc_t nxt_assoc_id;
+ };
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 38]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ nxt_sid: The SCTP stack places the next message's stream number in
+ this value.
+
+ nxt_flags: This field may contain any of the following flags and is
+ composed of a bitwise OR of these values.
+
+ SCTP_UNORDERED: This flag is present when the next message was
+ sent unordered.
+
+ SCTP_COMPLETE: This flag indicates that the entire message has
+ been received and is in the socket buffer. Note that this has
+ special implications with respect to the nxt_length field; see
+ the description for nxt_length below.
+
+ SCTP_NOTIFICATION: This flag is present when the next message is
+ not a user message but instead is a notification.
+
+ nxt_ppid: This value is the same information that was passed by the
+ upper layer in the peer application for the next message. Please
+ note that the SCTP stack performs no byte order modification of
+ this field. For example, if the DATA chunk has to contain a given
+ value in network byte order, the SCTP user has to perform the
+ ntohl() computation.
+
+ nxt_length: This value is the length of the message currently within
+ the socket buffer. This might NOT be the entire length of the
+ message, since a partial delivery may be in progress. Only if the
+ flag SCTP_COMPLETE is set in the nxt_flags field does this field
+ represent the size of the entire next message.
+
+ nxt_assoc_id: The association handle field of the next message,
+ nxt_assoc_id, holds the identifier for the association announced
+ in the SCTP_COMM_UP notification. All notifications for a given
+ association have the same identifier. This field is ignored for
+ one-to-one style sockets.
+
+5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO)
+
+ This cmsghdr structure specifies SCTP options for sendmsg().
+
+ +--------------+-------------+--------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+-------------+--------------------+
+ | IPPROTO_SCTP | SCTP_PRINFO | struct sctp_prinfo |
+ +--------------+-------------+--------------------+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 39]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The sctp_prinfo structure is defined below:
+
+ struct sctp_prinfo {
+ uint16_t pr_policy;
+ uint32_t pr_value;
+ };
+
+ pr_policy: This specifies which Partially Reliable SCTP (PR-SCTP)
+ policy is used. Using SCTP_PR_SCTP_NONE results in a reliable
+ transmission. When SCTP_PR_SCTP_TTL is used, the PR-SCTP policy
+ "timed reliability" defined in [RFC3758] is used. In this case,
+ the lifetime is provided in pr_value.
+
+ pr_value: The meaning of this field depends on the PR-SCTP policy
+ specified by the pr_policy field. It is ignored when
+ SCTP_PR_SCTP_NONE is specified. In the case of SCTP_PR_SCTP_TTL,
+ the lifetime in milliseconds is specified.
+
+ An sctp_prinfo item always corresponds to the data in msg_iov.
+
+5.3.8. SCTP AUTH Information Structure (SCTP_AUTHINFO)
+
+ This cmsghdr structure specifies SCTP options for sendmsg().
+
+ +--------------+---------------+----------------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+---------------+----------------------+
+ | IPPROTO_SCTP | SCTP_AUTHINFO | struct sctp_authinfo |
+ +--------------+---------------+----------------------+
+
+ The sctp_authinfo structure is defined below:
+
+ struct sctp_authinfo {
+ uint16_t auth_keynumber;
+ };
+
+ auth_keynumber: This specifies the shared key identifier used for
+ sending the user message.
+
+ An sctp_authinfo item always corresponds to the data in msg_iov.
+ Please note that the SCTP implementation must not bundle user
+ messages that need to be authenticated using different shared key
+ identifiers.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 40]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+5.3.9. SCTP Destination IPv4 Address Structure (SCTP_DSTADDRV4)
+
+ This cmsghdr structure specifies SCTP options for sendmsg().
+
+ +--------------+----------------+----------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+----------------+----------------+
+ | IPPROTO_SCTP | SCTP_DSTADDRV4 | struct in_addr |
+ +--------------+----------------+----------------+
+
+ This ancillary data can be used to provide more than one destination
+ address to sendmsg(). It can be used to implement sctp_sendv() using
+ sendmsg().
+
+5.3.10. SCTP Destination IPv6 Address Structure (SCTP_DSTADDRV6)
+
+ This cmsghdr structure specifies SCTP options for sendmsg().
+
+ +--------------+----------------+-----------------+
+ | cmsg_level | cmsg_type | cmsg_data[] |
+ +--------------+----------------+-----------------+
+ | IPPROTO_SCTP | SCTP_DSTADDRV6 | struct in6_addr |
+ +--------------+----------------+-----------------+
+
+ This ancillary data can be used to provide more than one destination
+ address to sendmsg(). It can be used to implement sctp_sendv() using
+ sendmsg().
+
+6. SCTP Events and Notifications
+
+ An SCTP application may need to understand and process events and
+ errors that happen on the SCTP stack. These events include network
+ status changes, association startups, remote operational errors, and
+ undeliverable messages. All of these can be essential for the
+ application.
+
+ When an SCTP application layer does a recvmsg(), the message read is
+ normally a data message from a peer endpoint. If the application
+ wishes to have the SCTP stack deliver notifications of non-data
+ events, it sets the appropriate socket option for the notifications
+ it wants. See Section 6.2 for these socket options. When a
+ notification arrives, recvmsg() returns the notification in the
+ application-supplied data buffer via msg_iov, and sets
+ MSG_NOTIFICATION in msg_flags.
+
+ This section details the notification structures. Every notification
+ structure carries some common fields that provide general
+ information.
+
+
+
+Stewart, et al. Informational [Page 41]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ A recvmsg() call will return only one notification at a time. Just
+ as when reading normal data, it may return part of a notification if
+ the msg_iov buffer is not large enough. If a single read is not
+ sufficient, msg_flags will have MSG_EOR clear. The user must finish
+ reading the notification before subsequent data can arrive.
+
+6.1. SCTP Notification Structure
+
+ The notification structure is defined as the union of all
+ notification types.
+
+ union sctp_notification {
+ struct sctp_tlv {
+ uint16_t sn_type; /* Notification type. */
+ uint16_t sn_flags;
+ uint32_t sn_length;
+ } sn_header;
+ struct sctp_assoc_change sn_assoc_change;
+ struct sctp_paddr_change sn_paddr_change;
+ struct sctp_remote_error sn_remote_error;
+ struct sctp_send_failed sn_send_failed;
+ struct sctp_shutdown_event sn_shutdown_event;
+ struct sctp_adaptation_event sn_adaptation_event;
+ struct sctp_pdapi_event sn_pdapi_event;
+ struct sctp_authkey_event sn_auth_event;
+ struct sctp_sender_dry_event sn_sender_dry_event;
+ struct sctp_send_failed_event sn_send_failed_event;
+ };
+
+ sn_type: The following list describes the SCTP notification and
+ event types for the field sn_type.
+
+ SCTP_ASSOC_CHANGE: This tag indicates that an association has
+ either been opened or closed. Refer to Section 6.1.1 for
+ details.
+
+ SCTP_PEER_ADDR_CHANGE: This tag indicates that an address that is
+ part of an existing association has experienced a change of
+ state (e.g., a failure or return to service of the reachability
+ of an endpoint via a specific transport address). Please see
+ Section 6.1.2 for data structure details.
+
+ SCTP_REMOTE_ERROR: The attached error message is an Operation
+ Error message received from the remote peer. It includes the
+ complete TLV sent by the remote endpoint. See Section 6.1.3
+ for the detailed format.
+
+
+
+
+
+Stewart, et al. Informational [Page 42]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SCTP_SEND_FAILED_EVENT: The attached datagram could not be sent
+ to the remote endpoint. This structure includes the original
+ SCTP_SNDINFO that was used in sending this message; i.e., this
+ structure uses the sctp_sndinfo per Section 6.1.11.
+
+ SCTP_SHUTDOWN_EVENT: The peer has sent a SHUTDOWN. No further
+ data should be sent on this socket.
+
+ SCTP_ADAPTATION_INDICATION: This notification holds the peer's
+ indicated adaptation layer. Please see Section 6.1.6.
+
+ SCTP_PARTIAL_DELIVERY_EVENT: This notification is used to tell a
+ receiver that the partial delivery has been aborted. This may
+ indicate that the association is about to be aborted. Please
+ see Section 6.1.7.
+
+ SCTP_AUTHENTICATION_EVENT: This notification is used to tell a
+ receiver that either an error occurred on authentication, or a
+ new key was made active. See Section 6.1.8.
+
+ SCTP_SENDER_DRY_EVENT: This notification is used to inform the
+ application that the sender has no more user data queued for
+ transmission or retransmission. See Section 6.1.9.
+
+ sn_flags: These are notification-specific flags.
+
+ sn_length: This is the length of the whole sctp_notification
+ structure, including the sn_type, sn_flags, and sn_length fields.
+
+6.1.1. SCTP_ASSOC_CHANGE
+
+ Communication notifications inform the application that an SCTP
+ association has either begun or ended. The identifier for a new
+ association is provided by this notification. The notification
+ information has the following format:
+
+ struct sctp_assoc_change {
+ uint16_t sac_type;
+ uint16_t sac_flags;
+ uint32_t sac_length;
+ uint16_t sac_state;
+ uint16_t sac_error;
+ uint16_t sac_outbound_streams;
+ uint16_t sac_inbound_streams;
+ sctp_assoc_t sac_assoc_id;
+ uint8_t sac_info[];
+ };
+
+
+
+
+Stewart, et al. Informational [Page 43]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sac_type: This field should be set to SCTP_ASSOC_CHANGE.
+
+ sac_flags: This field is currently unused.
+
+ sac_length: This field is the total length of the notification data,
+ including the notification header.
+
+ sac_state: This field holds one of a number of values that
+ communicate the event that happened to the association. These
+ values include
+
+ SCTP_COMM_UP: A new association is now ready, and data may be
+ exchanged with this peer. When an association has been
+ established successfully, this notification should be the
+ first one.
+
+ SCTP_COMM_LOST: The association has failed. The association is
+ now in the closed state. If SEND_FAILED notifications are
+ turned on, an SCTP_COMM_LOST is accompanied by a series of
+ SCTP_SEND_FAILED_EVENT events, one for each outstanding
+ message.
+
+ SCTP_RESTART: SCTP has detected that the peer has restarted.
+
+ SCTP_SHUTDOWN_COMP: The association has gracefully closed.
+
+ SCTP_CANT_STR_ASSOC: The association setup failed. If
+ non-blocking mode is set and data was sent (on a one-to-many
+ style socket), an SCTP_CANT_STR_ASSOC is accompanied by a
+ series of SCTP_SEND_FAILED_EVENT events, one for each
+ outstanding message.
+
+ sac_error: If the state was reached due to an error condition (e.g.,
+ SCTP_COMM_LOST), any relevant error information is available in
+ this field. This corresponds to the protocol error codes defined
+ in [RFC4960].
+
+ sac_outbound_streams and sac_inbound_streams: The maximum number of
+ streams allowed in each direction is available in
+ sac_outbound_streams and sac_inbound streams.
+
+ sac_assoc_id: The sac_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 44]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sac_info: If sac_state is SCTP_COMM_LOST and an ABORT chunk was
+ received for this association, sac_info[] contains the complete
+ ABORT chunk as defined in Section 3.3.7 of the SCTP specification
+ [RFC4960]. If sac_state is SCTP_COMM_UP or SCTP_RESTART, sac_info
+ may contain an array of uint8_t describing the features that the
+ current association supports. Features may include
+
+ SCTP_ASSOC_SUPPORTS_PR: Both endpoints support the protocol
+ extension described in [RFC3758].
+
+ SCTP_ASSOC_SUPPORTS_AUTH: Both endpoints support the protocol
+ extension described in [RFC4895].
+
+ SCTP_ASSOC_SUPPORTS_ASCONF: Both endpoints support the protocol
+ extension described in [RFC5061].
+
+ SCTP_ASSOC_SUPPORTS_MULTIBUF: For a one-to-many style socket, the
+ local endpoints use separate send and/or receive buffers for
+ each SCTP association.
+
+6.1.2. SCTP_PEER_ADDR_CHANGE
+
+ When a destination address of a multi-homed peer encounters a state
+ change, a peer address change event is sent. The notification has
+ the following format:
+
+ struct sctp_paddr_change {
+ uint16_t spc_type;
+ uint16_t spc_flags;
+ uint32_t spc_length;
+ struct sockaddr_storage spc_aaddr;
+ uint32_t spc_state;
+ uint32_t spc_error;
+ sctp_assoc_t spc_assoc_id;
+ }
+
+ spc_type: This field should be set to SCTP_PEER_ADDR_CHANGE.
+
+ spc_flags: This field is currently unused.
+
+ spc_length: This field is the total length of the notification data,
+ including the notification header.
+
+ spc_aaddr: The affected address field holds the remote peer's
+ address that is encountering the change of state.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 45]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ spc_state: This field holds one of a number of values that
+ communicate the event that happened to the address. They include
+
+ SCTP_ADDR_AVAILABLE: This address is now reachable. This
+ notification is provided whenever an address becomes reachable.
+
+ SCTP_ADDR_UNREACHABLE: The address specified can no longer be
+ reached. Any data sent to this address is rerouted to an
+ alternate until this address becomes reachable. This
+ notification is provided whenever an address becomes
+ unreachable.
+
+ SCTP_ADDR_REMOVED: The address is no longer part of the
+ association.
+
+ SCTP_ADDR_ADDED: The address is now part of the association.
+
+ SCTP_ADDR_MADE_PRIM: This address has now been made the primary
+ destination address. This notification is provided whenever an
+ address is made primary.
+
+ spc_error: If the state was reached due to any error condition
+ (e.g., SCTP_ADDR_UNREACHABLE), any relevant error information is
+ available in this field.
+
+ spc_assoc_id: The spc_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+6.1.3. SCTP_REMOTE_ERROR
+
+ A remote peer may send an Operation Error message to its peer. This
+ message indicates a variety of error conditions on an association.
+ The entire ERROR chunk as it appears on the wire is included in an
+ SCTP_REMOTE_ERROR event. Please refer to the SCTP specification
+ [RFC4960] and any extensions for a list of possible error formats.
+ An SCTP error notification has the following format:
+
+ struct sctp_remote_error {
+ uint16_t sre_type;
+ uint16_t sre_flags;
+ uint32_t sre_length;
+ uint16_t sre_error;
+ sctp_assoc_t sre_assoc_id;
+ uint8_t sre_data[];
+ };
+
+
+
+
+Stewart, et al. Informational [Page 46]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sre_type: This field should be set to SCTP_REMOTE_ERROR.
+
+ sre_flags: This field is currently unused.
+
+ sre_length: This field is the total length of the notification data,
+ including the notification header and the contents of sre_data.
+
+ sre_error: This value represents one of the Operation Error causes
+ defined in the SCTP specification [RFC4960], in network byte
+ order.
+
+ sre_assoc_id: The sre_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+ sre_data: This contains the ERROR chunk as defined in Section 3.3.10
+ of the SCTP specification [RFC4960].
+
+6.1.4. SCTP_SEND_FAILED - DEPRECATED
+
+ Please note that this notification is deprecated. Use
+ SCTP_SEND_FAILED_EVENT instead.
+
+ If SCTP cannot deliver a message, it can return back the message as a
+ notification if the SCTP_SEND_FAILED event is enabled. The
+ notification has the following format:
+
+ struct sctp_send_failed {
+ uint16_t ssf_type;
+ uint16_t ssf_flags;
+ uint32_t ssf_length;
+ uint32_t ssf_error;
+ struct sctp_sndrcvinfo ssf_info;
+ sctp_assoc_t ssf_assoc_id;
+ uint8_t ssf_data[];
+ };
+
+ ssf_type: This field should be set to SCTP_SEND_FAILED.
+
+ ssf_flags: The flag value will take one of the following values:
+
+ SCTP_DATA_UNSENT: This value indicates that the data was never
+ put on the wire.
+
+ SCTP_DATA_SENT: This value indicates that the data was put on the
+ wire. Note that this does not necessarily mean that the data
+ was (or was not) successfully delivered.
+
+
+
+Stewart, et al. Informational [Page 47]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ ssf_length: This field is the total length of the notification data,
+ including the notification header and the payload in ssf_data.
+
+ ssf_error: This value represents the reason why the send failed, and
+ if set, will be an SCTP protocol error code as defined in
+ Section 3.3.10 of [RFC4960].
+
+ ssf_info: This field includes the ancillary data (struct
+ sctp_sndrcvinfo) used to send the undelivered message. Regardless
+ of whether ancillary data is used or not, the ssf_info.sinfo_flags
+ field indicates whether the complete message or only part of the
+ message is returned in ssf_data. If only part of the message is
+ returned, it means that the part that is not present has been sent
+ successfully to the peer.
+
+ If the complete message cannot be sent, the SCTP_DATA_NOT_FRAG
+ flag is set in ssf_info.sinfo_flags. If the first part of the
+ message is sent successfully, SCTP_DATA_LAST_FRAG is set. This
+ means that the tail end of the message is returned in ssf_data.
+
+ ssf_assoc_id: The ssf_assoc_id field, ssf_assoc_id, holds the
+ identifier for the association. All notifications for a given
+ association have the same association identifier. For a one-to-
+ one style socket, this field is ignored.
+
+ ssf_data: The undelivered message or part of the undelivered message
+ will be present in the ssf_data field. Note that the
+ ssf_info.sinfo_flags field as noted above should be used to
+ determine whether a complete message or just a piece of the
+ message is present. Note that only user data is present in this
+ field; any chunk headers or SCTP common headers must be removed by
+ the SCTP stack.
+
+6.1.5. SCTP_SHUTDOWN_EVENT
+
+ When a peer sends a SHUTDOWN, SCTP delivers this notification to
+ inform the application that it should cease sending data.
+
+ struct sctp_shutdown_event {
+ uint16_t sse_type;
+ uint16_t sse_flags;
+ uint32_t sse_length;
+ sctp_assoc_t sse_assoc_id;
+ };
+
+ sse_type: This field should be set to SCTP_SHUTDOWN_EVENT.
+
+ sse_flags: This field is currently unused.
+
+
+
+Stewart, et al. Informational [Page 48]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sse_length: This field is the total length of the notification data,
+ including the notification header. It will generally be
+ sizeof(struct sctp_shutdown_event).
+
+ sse_assoc_id: The sse_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+6.1.6. SCTP_ADAPTATION_INDICATION
+
+ When a peer sends an Adaptation Layer Indication parameter as
+ described in [RFC5061], SCTP delivers this notification to inform the
+ application about the peer's adaptation layer indication.
+
+ struct sctp_adaptation_event {
+ uint16_t sai_type;
+ uint16_t sai_flags;
+ uint32_t sai_length;
+ uint32_t sai_adaptation_ind;
+ sctp_assoc_t sai_assoc_id;
+ };
+
+ sai_type: This field should be set to SCTP_ADAPTATION_INDICATION.
+
+ sai_flags: This field is currently unused.
+
+ sai_length: This field is the total length of the notification data,
+ including the notification header. It will generally be
+ sizeof(struct sctp_adaptation_event).
+
+ sai_adaptation_ind: This field holds the bit array sent by the peer
+ in the Adaptation Layer Indication parameter.
+
+ sai_assoc_id: The sai_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+6.1.7. SCTP_PARTIAL_DELIVERY_EVENT
+
+ When a receiver is engaged in a partial delivery of a message, this
+ notification will be used to indicate various events.
+
+ struct sctp_pdapi_event {
+ uint16_t pdapi_type;
+ uint16_t pdapi_flags;
+ uint32_t pdapi_length;
+
+
+
+Stewart, et al. Informational [Page 49]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ uint32_t pdapi_indication;
+ uint32_t pdapi_stream;
+ uint32_t pdapi_seq;
+ sctp_assoc_t pdapi_assoc_id;
+ };
+
+ pdapi_type: This field should be set to SCTP_PARTIAL_DELIVERY_EVENT.
+
+ pdapi_flags: This field is currently unused.
+
+ pdapi_length: This field is the total length of the notification
+ data, including the notification header. It will generally be
+ sizeof(struct sctp_pdapi_event).
+
+ pdapi_indication: This field holds the indication being sent to the
+ application. Currently, there is only one defined value:
+
+ SCTP_PARTIAL_DELIVERY_ABORTED: This indicates that the partial
+ delivery of a user message has been aborted. This happens, for
+ example, if an association is aborted while a partial delivery
+ is going on or the user message gets abandoned using PR-SCTP
+ while the partial delivery of this message is going on.
+
+ pdapi_stream: This field holds the stream on which the partial
+ delivery event happened.
+
+ pdapi_seq: This field holds the stream sequence number that was
+ being partially delivered.
+
+ pdapi_assoc_id: The pdapi_assoc_id field holds the identifier for
+ the association. All notifications for a given association have
+ the same association identifier. For a one-to-one style socket,
+ this field is ignored.
+
+6.1.8. SCTP_AUTHENTICATION_EVENT
+
+ [RFC4895] defines an extension to authenticate SCTP messages. The
+ following notification is used to report different events relating to
+ the use of this extension.
+
+ struct sctp_authkey_event {
+ uint16_t auth_type;
+ uint16_t auth_flags;
+ uint32_t auth_length;
+ uint16_t auth_keynumber;
+ uint32_t auth_indication;
+ sctp_assoc_t auth_assoc_id;
+ };
+
+
+
+Stewart, et al. Informational [Page 50]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ auth_type: This field should be set to SCTP_AUTHENTICATION_EVENT.
+
+ auth_flags: This field is currently unused.
+
+ auth_length: This field is the total length of the notification
+ data, including the notification header. It will generally be
+ sizeof(struct sctp_authkey_event).
+
+ auth_keynumber: This field holds the key number for the affected key
+ indicated in the event (depends on auth_indication).
+
+ auth_indication: This field holds the error or indication being
+ reported. The following values are currently defined:
+
+ SCTP_AUTH_NEW_KEY: This report indicates that a new key has been
+ made active (used for the first time by the peer) and is now
+ the active key. The auth_keynumber field holds the user-
+ specified key number.
+
+ SCTP_AUTH_NO_AUTH: This report indicates that the peer does not
+ support SCTP authentication as defined in [RFC4895].
+
+ SCTP_AUTH_FREE_KEY: This report indicates that the SCTP
+ implementation will no longer use the key identifier specified
+ in auth_keynumber.
+
+ auth_assoc_id: The auth_assoc_id field holds the identifier for the
+ association. All notifications for a given association have the
+ same association identifier. For a one-to-one style socket, this
+ field is ignored.
+
+6.1.9. SCTP_SENDER_DRY_EVENT
+
+ When the SCTP stack has no more user data to send or retransmit, this
+ notification is given to the user. Also, at the time when a user app
+ subscribes to this event, if there is no data to be sent or
+ retransmit, the stack will immediately send up this notification.
+
+ struct sctp_sender_dry_event {
+ uint16_t sender_dry_type;
+ uint16_t sender_dry_flags;
+ uint32_t sender_dry_length;
+ sctp_assoc_t sender_dry_assoc_id;
+ };
+
+ sender_dry_type: This field should be set to SCTP_SENDER_DRY_EVENT.
+
+ sender_dry_flags: This field is currently unused.
+
+
+
+Stewart, et al. Informational [Page 51]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sender_dry_length: This field is the total length of the
+ notification data, including the notification header. It will
+ generally be sizeof(struct sctp_sender_dry_event).
+
+ sender_dry_assoc_id: The sender_dry_assoc_id field holds the
+ identifier for the association. All notifications for a given
+ association have the same association identifier. For a one-to-
+ one style socket, this field is ignored.
+
+6.1.10. SCTP_NOTIFICATIONS_STOPPED_EVENT
+
+ SCTP notifications, when subscribed to, are reliable. They are
+ always delivered as long as there is space in the socket receive
+ buffer. However, if an implementation experiences a notification
+ storm, it may run out of socket buffer space. When this occurs, it
+ may wish to disable notifications. If the implementation chooses to
+ do this, it will append a final notification
+ SCTP_NOTIFICATIONS_STOPPED_EVENT. This notification is a union
+ sctp_notification, where only the sctp_tlv structure (see the union
+ above) is used. It only contains this type in the sn_type field, the
+ sn_length field set to the size of an sctp_tlv structure, and the
+ sn_flags set to 0. If an application receives this notification, it
+ will need to re-subscribe to any notifications of interest to it,
+ except for the sctp_data_io_event (note that SCTP_EVENTS is
+ deprecated).
+
+ An endpoint is automatically subscribed to this event as soon as it
+ is subscribed to any event other than data io events.
+
+6.1.11. SCTP_SEND_FAILED_EVENT
+
+ If SCTP cannot deliver a message, it can return back the message as a
+ notification if the SCTP_SEND_FAILED_EVENT event is enabled. The
+ notification has the following format:
+
+ struct sctp_send_failed_event {
+ uint16_t ssfe_type;
+ uint16_t ssfe_flags;
+ uint32_t ssfe_length;
+ uint32_t ssfe_error;
+ struct sctp_sndinfo ssfe_info;
+ sctp_assoc_t ssfe_assoc_id;
+ uint8_t ssfe_data[];
+ };
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 52]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ ssfe_type: This field should be set to SCTP_SEND_FAILED_EVENT.
+
+ ssfe_flags: The flag value will take one of the following values:
+
+ SCTP_DATA_UNSENT: This value indicates that the data was never
+ put on the wire.
+
+ SCTP_DATA_SENT: This value indicates that the data was put on the
+ wire. Note that this does not necessarily mean that the data
+ was (or was not) successfully delivered.
+
+ ssfe_length: This field is the total length of the notification
+ data, including the notification header and the payload in
+ ssf_data.
+
+ ssfe_error: This value represents the reason why the send failed,
+ and if set, will be an SCTP protocol error code as defined in
+ Section 3.3.10 of [RFC4960].
+
+ ssfe_info: This field includes the ancillary data (struct
+ sctp_sndinfo) used to send the undelivered message. Regardless of
+ whether ancillary data is used or not, the ssfe_info.sinfo_flags
+ field indicates whether the complete message or only part of the
+ message is returned in ssf_data. If only part of the message is
+ returned, it means that the part that is not present has been sent
+ successfully to the peer.
+
+ If the complete message cannot be sent, the SCTP_DATA_NOT_FRAG
+ flag is set in ssfe_info.sinfo_flags. If the first part of the
+ message is sent successfully, SCTP_DATA_LAST_FRAG is set. This
+ means that the tail end of the message is returned in ssf_data.
+
+ ssfe_assoc_id: The ssfe_assoc_id field, ssf_assoc_id, holds the
+ identifier for the association. All notifications for a given
+ association have the same association identifier. For a one-to-
+ one style socket, this field is ignored.
+
+ ssfe_data: The undelivered message or part of the undelivered
+ message will be present in the ssf_data field. Note that the
+ ssf_info.sinfo_flags field as noted above should be used to
+ determine whether a complete message or just a piece of the
+ message is present. Note that only user data is present in this
+ field; any chunk headers or SCTP common headers must be removed by
+ the SCTP stack.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 53]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+6.2. Notification Interest Options
+
+6.2.1. SCTP_EVENTS Option - DEPRECATED
+
+ Please note that this option is deprecated. Use the SCTP_EVENT
+ option described in Section 6.2.2 instead.
+
+ To receive SCTP event notifications, an application registers its
+ interest by setting the SCTP_EVENTS socket option. The application
+ then uses recvmsg() to retrieve notifications. A notification is
+ stored in the data part (msg_iov) of the msghdr structure. The
+ socket option uses the following structure:
+
+ struct sctp_event_subscribe {
+ uint8_t sctp_data_io_event;
+ uint8_t sctp_association_event;
+ uint8_t sctp_address_event;
+ uint8_t sctp_send_failure_event;
+ uint8_t sctp_peer_error_event;
+ uint8_t sctp_shutdown_event;
+ uint8_t sctp_partial_delivery_event;
+ uint8_t sctp_adaptation_layer_event;
+ uint8_t sctp_authentication_event;
+ uint8_t sctp_sender_dry_event;
+ };
+
+ sctp_data_io_event: Setting this flag to 1 will cause the reception
+ of SCTP_SNDRCV information on a per-message basis. The
+ application will need to use the recvmsg() interface so that it
+ can receive the event information contained in the msg_control
+ field. Setting the flag to 0 will disable the reception of the
+ message control information. Note that this flag is not really a
+ notification and is stored in the ancillary data (msg_control),
+ not in the data part (msg_iov).
+
+ sctp_association_event: Setting this flag to 1 will enable the
+ reception of association event notifications. Setting the flag to
+ 0 will disable association event notifications.
+
+ sctp_address_event: Setting this flag to 1 will enable the reception
+ of address event notifications. Setting the flag to 0 will
+ disable address event notifications.
+
+ sctp_send_failure_event: Setting this flag to 1 will enable the
+ reception of send failure event notifications. Setting the flag
+ to 0 will disable send failure event notifications.
+
+
+
+
+
+Stewart, et al. Informational [Page 54]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sctp_peer_error_event: Setting this flag to 1 will enable the
+ reception of peer error event notifications. Setting the flag to
+ 0 will disable peer error event notifications.
+
+ sctp_shutdown_event: Setting this flag to 1 will enable the
+ reception of shutdown event notifications. Setting the flag to 0
+ will disable shutdown event notifications.
+
+ sctp_partial_delivery_event: Setting this flag to 1 will enable the
+ reception of partial delivery event notifications. Setting the
+ flag to 0 will disable partial delivery event notifications.
+
+ sctp_adaptation_layer_event: Setting this flag to 1 will enable the
+ reception of adaptation layer event notifications. Setting the
+ flag to 0 will disable adaptation layer event notifications.
+
+ sctp_authentication_event: Setting this flag to 1 will enable the
+ reception of authentication layer event notifications. Setting
+ the flag to 0 will disable authentication layer event
+ notifications.
+
+ sctp_sender_dry_event: Setting this flag to 1 will enable the
+ reception of sender dry event notifications. Setting the flag to
+ 0 will disable sender dry event notifications.
+
+ An example where an application would like to receive data_io_events
+ and association_events but no others would be as follows:
+
+ {
+ struct sctp_event_subscribe events;
+
+ memset(&events, 0, sizeof(events));
+
+ events.sctp_data_io_event = 1;
+ events.sctp_association_event = 1;
+
+ setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events));
+ }
+
+ Note that for one-to-many style SCTP sockets, the caller of recvmsg()
+ receives ancillary data and notifications for all associations bound
+ to the file descriptor. For one-to-one style SCTP sockets, the
+ caller receives ancillary data and notifications only for the single
+ association bound to the file descriptor.
+
+ By default, both the one-to-one style and the one-to-many style
+ socket do not subscribe to any notification.
+
+
+
+
+Stewart, et al. Informational [Page 55]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+6.2.2. SCTP_EVENT Option
+
+ The SCTP_EVENTS socket option has one issue for future compatibility.
+ As new features are added, the structure (sctp_event_subscribe) must
+ be expanded. This can cause an application binary interface (ABI)
+ issue unless an implementation has added padding at the end of the
+ structure. To avoid this problem, SCTP_EVENTS has been deprecated
+ and a new socket option SCTP_EVENT has taken its place. The option
+ is used with the following structure:
+
+ struct sctp_event {
+ sctp_assoc_t se_assoc_id;
+ uint16_t se_type;
+ uint8_t se_on;
+ };
+
+ se_assoc_id: The se_assoc_id field is ignored for one-to-one style
+ sockets. For one-to-many style sockets, this field can be a
+ particular association identifier or SCTP_{FUTURE|CURRENT|
+ ALL}_ASSOC.
+
+ se_type: The se_type field can be filled with any value that would
+ show up in the respective sn_type field (in the sctp_tlv structure
+ of the notification).
+
+ se_on: The se_on field is set to 1 to turn on an event and set to 0
+ to turn off an event.
+
+ To use this option, the user fills in this structure and then calls
+ setsockopt() to turn on or off an individual event. The following is
+ an example use of this option:
+
+ {
+ struct sctp_event event;
+
+ memset(&event, 0, sizeof(event));
+
+ event.se_assoc_id = SCTP_FUTURE_ASSOC;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 1;
+ setsockopt(sd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event));
+ }
+
+ By default, both the one-to-one style and the one-to-many style
+ socket do not subscribe to any notification.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 56]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+7. Common Operations for Both Styles
+
+7.1. send(), recv(), sendto(), and recvfrom()
+
+ Applications can use send() and sendto() to transmit data to the peer
+ of an SCTP endpoint. recv() and recvfrom() can be used to receive
+ data from the peer.
+
+ The function prototypes are
+
+ ssize_t send(int sd,
+ const void *msg,
+ size_t len,
+ int flags);
+
+ ssize_t sendto(int sd,
+ const void *msg,
+ size_t len,
+ int flags,
+ const struct sockaddr *to,
+ socklen_t tolen);
+
+ ssize_t recv(int sd,
+ void *buf,
+ size_t len,
+ int flags);
+
+ ssize_t recvfrom(int sd,
+ void *buf,
+ size_t len,
+ int flags,
+ struct sockaddr *from,
+ socklen_t *fromlen);
+
+ and the arguments are
+
+ sd: The socket descriptor of an SCTP endpoint.
+
+ msg: The message to be sent.
+
+ len: The size of the message or the size of the buffer.
+
+ to: One of the peer addresses of the association to be used to send
+ the message.
+
+ tolen: The size of the address.
+
+ buf: The buffer to store a received message.
+
+
+
+Stewart, et al. Informational [Page 57]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ from: The buffer to store the peer address used to send the received
+ message.
+
+ fromlen: The size of the from address.
+
+ flags: (described below).
+
+ These calls give access to only basic SCTP protocol features. If
+ either peer in the association uses multiple streams, or sends
+ unordered data, these calls will usually be inadequate and may
+ deliver the data in unpredictable ways.
+
+ SCTP has the concept of multiple streams in one association. The
+ above calls do not allow the caller to specify on which stream a
+ message should be sent. The system uses stream 0 as the default
+ stream for send() and sendto(). recv() and recvfrom() return data
+ from any stream, but the caller cannot distinguish the different
+ streams. This may result in data seeming to arrive out of order.
+ Similarly, if a DATA chunk is sent unordered, recv() and recvfrom()
+ provide no indication.
+
+ SCTP is message based. The msg buffer above in send() and sendto()
+ is considered to be a single message. This means that if the caller
+ wants to send a message that is composed by several buffers, the
+ caller needs to combine them before calling send() or sendto().
+ Alternately, the caller can use sendmsg() to do that without
+ combining them. Sending a message using send() or sendto() is atomic
+ unless explicit EOR marking is enabled on the socket specified by sd.
+ Using sendto() on a non-connected one-to-one style socket for
+ implicit connection setup may or may not work, depending on the SCTP
+ implementation. recv() and recvfrom() cannot distinguish message
+ boundaries (i.e., there is no way to observe the MSG_EOR flag to
+ detect partial delivery).
+
+ When receiving, if the buffer supplied is not large enough to hold a
+ complete message, the receive call acts like a stream socket and
+ returns as much data as will fit in the buffer.
+
+ Note that the send() and recv() calls may not be used for a one-to-
+ many style socket.
+
+ Note that if an application calls a send() or sendto() function with
+ no user data, the SCTP implementation should reject the request with
+ an appropriate error message. An implementation is not allowed to
+ send a DATA chunk with no user data [RFC4960].
+
+
+
+
+
+
+Stewart, et al. Informational [Page 58]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+7.2. setsockopt() and getsockopt()
+
+ Applications use setsockopt() and getsockopt() to set or retrieve
+ socket options. Socket options are used to change the default
+ behavior of socket calls. They are described in Section 8.
+
+ The function prototypes are
+
+ int getsockopt(int sd,
+ int level,
+ int optname,
+ void *optval,
+ socklen_t *optlen);
+
+ and
+
+ int setsockopt(int sd,
+ int level,
+ int optname,
+ const void *optval,
+ socklen_t optlen);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ level: Set to IPPROTO_SCTP for all SCTP options.
+
+ optname: The option name.
+
+ optval: The buffer to store the value of the option.
+
+ optlen: The size of the buffer (or the length of the option
+ returned).
+
+ These functions return 0 on success and -1 in case of an error.
+
+ All socket options set on a one-to-one style listening socket also
+ apply to all future accepted sockets. For one-to-many style sockets,
+ often a socket option will pass a structure that includes an assoc_id
+ field. This field can be filled with the association identifier of a
+ particular association and unless otherwise specified can be filled
+ with one of the following constants:
+
+ SCTP_FUTURE_ASSOC: Specifies that only future associations created
+ after this socket option will be affected by this call.
+
+
+
+
+
+Stewart, et al. Informational [Page 59]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SCTP_CURRENT_ASSOC: Specifies that only currently existing
+ associations will be affected by this call, and future
+ associations will still receive the previous default value.
+
+ SCTP_ALL_ASSOC: Specifies that all current and future associations
+ will be affected by this call.
+
+7.3. read() and write()
+
+ Applications can use read() and write() to receive and send data from
+ and to a peer. They have the same semantics as recv() and send(),
+ except that the flags parameter cannot be used.
+
+7.4. getsockname()
+
+ Applications use getsockname() to retrieve the locally bound socket
+ address of the specified socket. This is especially useful if the
+ caller let SCTP choose a local port. This call is for single-homed
+ endpoints. It does not work well with multi-homed endpoints. See
+ Section 9.5 for a multi-homed version of the call.
+
+ The function prototype is
+
+ int getsockname(int sd,
+ struct sockaddr *address,
+ socklen_t *len);
+
+ and the arguments are
+
+ sd: The socket descriptor to be queried.
+
+ address: On return, one locally bound address (chosen by the SCTP
+ stack) is stored in this buffer. If the socket is an IPv4 socket,
+ the address will be IPv4. If the socket is an IPv6 socket, the
+ address will be either an IPv6 or IPv4 address.
+
+ len: The caller should set the length of the address here. On
+ return, this is set to the length of the returned address.
+
+ getsockname() returns 0 on success and -1 in case of an error.
+
+ If the actual length of the address is greater than the length of the
+ supplied sockaddr structure, the stored address will be truncated.
+
+ If the socket has not been bound to a local name, the value stored in
+ the object pointed to by address is unspecified.
+
+
+
+
+
+Stewart, et al. Informational [Page 60]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+7.5. Implicit Association Setup
+
+ The application can begin sending and receiving data using the
+ sendmsg()/recvmsg() or sendto()/recvfrom() calls, without going
+ through any explicit association setup procedures (i.e., no connect()
+ calls required).
+
+ Whenever sendmsg() or sendto() is called and the SCTP stack at the
+ sender finds that no association exists between the sender and the
+ intended receiver (identified by the address passed either in the
+ msg_name field of the msghdr structure in the sendmsg() call or the
+ dest_addr field in the sendto() call), the SCTP stack will
+ automatically set up an association to the intended receiver.
+
+ Upon successful association setup, an SCTP_COMM_UP notification will
+ be dispatched to the socket at both the sender and receiver side.
+ This notification can be read by the recvmsg() system call (see
+ Section 3.1.4).
+
+ Note that if the SCTP stack at the sender side supports bundling, the
+ first user message may be bundled with the COOKIE ECHO message
+ [RFC4960].
+
+ When the SCTP stack sets up a new association implicitly, the
+ SCTP_INIT type ancillary data may also be passed along (see
+ Section 5.3.1 for details of the data structures) to change some
+ parameters used in setting up a new association.
+
+ If this information is not present in the sendmsg() call, or if the
+ implicit association setup is triggered by a sendto() call, the
+ default association initialization parameters will be used. These
+ default association parameters may be set with respective
+ setsockopt() calls or be left to the system defaults.
+
+ Implicit association setup cannot be initiated by send() calls.
+
+8. Socket Options
+
+ The following subsection describes various SCTP-level socket options
+ that are common to both styles. SCTP associations can be
+ multi-homed. Therefore, certain option parameters include a
+ sockaddr_storage structure to select to which peer address the option
+ should be applied.
+
+ For the one-to-many style sockets, an sctp_assoc_t (association
+ identifier) parameter is used to identify the association instance
+ that the operation affects. So it must be set when using this style.
+
+
+
+
+Stewart, et al. Informational [Page 61]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ For the one-to-one style sockets and branched-off one-to-many style
+ sockets (see Section 9.2), this association ID parameter is ignored.
+
+ Note that socket- or IP-level options are set or retrieved per
+ socket. This means that for one-to-many style sockets, the options
+ will be applied to all associations (similar to using SCTP_ALL_ASSOC
+ as the association identifier) belonging to the socket. For the one-
+ to-one style, these options will be applied to all peer addresses of
+ the association controlled by the socket. Applications should be
+ careful in setting those options.
+
+ For some IP stacks, getsockopt() is read-only, so a new interface
+ will be needed when information must be passed both into and out of
+ the SCTP stack. The syntax for sctp_opt_info() is
+
+ int sctp_opt_info(int sd,
+ sctp_assoc_t id,
+ int opt,
+ void *arg,
+ socklen_t *size);
+
+ The sctp_opt_info() call is a replacement for getsockopt() only and
+ will not set any options associated with the specified socket. A
+ setsockopt() call must be used to set any writable option.
+
+ For one-to-many style sockets, id specifies the association to query.
+ For one-to-one style sockets, id is ignored. For one-to-many style
+ sockets, any association identifier in the structure provided as arg
+ is ignored, and id takes precedence.
+
+ Note that SCTP_CURRENT_ASSOC and SCTP_ALL_ASSOC cannot be used with
+ sctp_opt_info() or in getsockopt() calls. Using them will result in
+ an error (returning -1 and errno set to EINVAL). SCTP_FUTURE_ASSOC
+ can be used to query information for future associations.
+
+ The field opt specifies which SCTP socket option to get. It can get
+ any socket option currently supported that requests information
+ (either read/write options or read-only) such as
+
+ SCTP_RTOINFO
+
+ SCTP_ASSOCINFO
+
+ SCTP_PRIMARY_ADDR
+
+ SCTP_PEER_ADDR_PARAMS
+
+ SCTP_DEFAULT_SEND_PARAM
+
+
+
+Stewart, et al. Informational [Page 62]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ SCTP_MAX_SEG
+
+ SCTP_AUTH_ACTIVE_KEY
+
+ SCTP_DELAYED_SACK
+
+ SCTP_MAX_BURST
+
+ SCTP_CONTEXT
+
+ SCTP_EVENT
+
+ SCTP_DEFAULT_SNDINFO
+
+ SCTP_DEFAULT_PRINFO
+
+ SCTP_STATUS
+
+ SCTP_GET_PEER_ADDR_INFO
+
+ SCTP_PEER_AUTH_CHUNKS
+
+ SCTP_LOCAL_AUTH_CHUNKS
+
+ The arg field is an option-specific structure buffer provided by the
+ caller. See the rest of this section for more information on these
+ options and option-specific structures.
+
+ sctp_opt_info() returns 0 on success, or on failure returns -1 and
+ sets errno to the appropriate error code.
+
+8.1. Read/Write Options
+
+8.1.1. Retransmission Timeout Parameters (SCTP_RTOINFO)
+
+ The protocol parameters used to initialize and limit the
+ retransmission timeout (RTO) are tunable. See [RFC4960] for more
+ information on how these parameters are used in RTO calculation.
+
+ The following structure is used to access and modify these
+ parameters:
+
+ struct sctp_rtoinfo {
+ sctp_assoc_t srto_assoc_id;
+ uint32_t srto_initial;
+ uint32_t srto_max;
+ uint32_t srto_min;
+ };
+
+
+
+Stewart, et al. Informational [Page 63]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ srto_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, the application may fill
+ in an association identifier or SCTP_FUTURE_ASSOC. It is an error
+ to use SCTP_{CURRENT|ALL}_ASSOC in srto_assoc_id.
+
+ srto_initial: This parameter contains the initial RTO value.
+
+ srto_max and srto_min: These parameters contain the maximum and
+ minimum bounds for all RTOs.
+
+ All times are given in milliseconds. A value of 0, when modifying
+ the parameters, indicates that the current value should not be
+ changed.
+
+ To access or modify these parameters, the application should call
+ getsockopt() or setsockopt(), respectively, with the option name
+ SCTP_RTOINFO.
+
+8.1.2. Association Parameters (SCTP_ASSOCINFO)
+
+ This option is used to both examine and set various association and
+ endpoint parameters. See [RFC4960] for more information on how these
+ parameters are used.
+
+ The following structure is used to access and modify these
+ parameters:
+
+ struct sctp_assocparams {
+ sctp_assoc_t sasoc_assoc_id;
+ uint16_t sasoc_asocmaxrxt;
+ uint16_t sasoc_number_peer_destinations;
+ uint32_t sasoc_peer_rwnd;
+ uint32_t sasoc_local_rwnd;
+ uint32_t sasoc_cookie_life;
+ };
+
+ sasoc_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, the application may fill
+ in an association identifier or SCTP_FUTURE_ASSOC. It is an error
+ to use SCTP_{CURRENT|ALL}_ASSOC in sasoc_assoc_id.
+
+ sasoc_asocmaxrxt: This parameter contains the maximum retransmission
+ attempts to make for the association.
+
+ sasoc_number_peer_destinations: This parameter is the number of
+ destination addresses that the peer has.
+
+
+
+
+
+Stewart, et al. Informational [Page 64]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sasoc_peer_rwnd: This parameter holds the current value of the
+ peer's rwnd (reported in the last selective acknowledgment (SACK))
+ minus any outstanding data (i.e., data in flight).
+
+ sasoc_local_rwnd: This parameter holds the last reported rwnd that
+ was sent to the peer.
+
+ sasoc_cookie_life: This parameter is the association's cookie life
+ value used when issuing cookies.
+
+ The value of sasoc_peer_rwnd is meaningless when examining endpoint
+ information (i.e., it is only valid when examining information on a
+ specific association).
+
+ All time values are given in milliseconds. A value of 0, when
+ modifying the parameters, indicates that the current value should not
+ be changed.
+
+ The values of sasoc_asocmaxrxt and sasoc_cookie_life may be set on
+ either an endpoint or association basis. The rwnd and destination
+ counts (sasoc_number_peer_destinations, sasoc_peer_rwnd,
+ sasoc_local_rwnd) are not settable, and any value placed in these is
+ ignored.
+
+ To access or modify these parameters, the application should call
+ getsockopt() or setsockopt(), respectively, with the option name
+ SCTP_ASSOCINFO.
+
+ The maximum number of retransmissions before an address is considered
+ unreachable is also tunable, but is address-specific, so it is
+ covered in a separate option. If an application attempts to set the
+ value of the association's maximum retransmission parameter to more
+ than the sum of all maximum retransmission parameters, setsockopt()
+ may return an error. The reason for this, from Section 8.2 of
+ [RFC4960], is as follows:
+
+ Note: When configuring the SCTP endpoint, the user should avoid
+ having the value of 'Association.Max.Retrans' (sasoc_maxrxt in
+ this option) larger than the summation of the 'Path.Max.Retrans'
+ (see spp_pathmaxrxt in Section 8.1.12) of all of the destination
+ addresses for the remote endpoint. Otherwise, all of the
+ destination addresses may become inactive while the endpoint still
+ considers the peer endpoint reachable.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 65]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.1.3. Initialization Parameters (SCTP_INITMSG)
+
+ Applications can specify protocol parameters for the default
+ association initialization. The structure used to access and modify
+ these parameters is defined in Section 5.3.1. The option name
+ argument to setsockopt() and getsockopt() is SCTP_INITMSG.
+
+ Setting initialization parameters is effective only on an unconnected
+ socket (for one-to-many style sockets, only future associations are
+ affected by the change).
+
+8.1.4. SO_LINGER
+
+ An application can use this option to perform the SCTP ABORT
+ primitive. This option affects all associations related to the
+ socket.
+
+ The linger option structure is
+
+ struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+ };
+
+ To enable the option, set l_onoff to 1. If the l_linger value is set
+ to 0, calling close() is the same as the ABORT primitive. If the
+ value is set to a negative value, the setsockopt() call will return
+ an error. If the value is set to a positive value linger_time, the
+ close() can be blocked for at most linger_time. Please note that the
+ time unit is in seconds, according to POSIX, but might be different
+ on specific platforms. If the graceful shutdown phase does not
+ finish during this period, close() will return, but the graceful
+ shutdown phase will continue in the system.
+
+ Note that this is a socket-level option, not an SCTP-level option.
+ When using this option, an application must specify a level of
+ SOL_SOCKET in the call.
+
+8.1.5. SCTP_NODELAY
+
+ This option turns on/off any Nagle-like algorithm. This means that
+ packets are generally sent as soon as possible, and no unnecessary
+ delays are introduced, at the cost of more packets in the network.
+ In particular, not using any Nagle-like algorithm might reduce the
+ bundling of small user messages in cases where this would require an
+ additional delay.
+
+ Turning this option on disables any Nagle-like algorithm.
+
+
+
+Stewart, et al. Informational [Page 66]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+8.1.6. SO_RCVBUF
+
+ This option sets the receive buffer size in octets. For SCTP one-to-
+ one style sockets, this option controls the receiver window size.
+ For one-to-many style sockets, the meaning is implementation
+ dependent. It might control the receive buffer for each association
+ bound to the socket descriptor, or it might control the receive
+ buffer for the whole socket. This option expects an integer.
+
+ Note that this is a socket-level option, not an SCTP-level option.
+ When using this option, an application must specify a level of
+ SOL_SOCKET in the call.
+
+8.1.7. SO_SNDBUF
+
+ This option sets the send buffer size. For SCTP one-to-one style
+ sockets, this option controls the amount of data SCTP may have
+ waiting in internal buffers to be sent. This option therefore bounds
+ the maximum size of data that can be sent in a single send call. For
+ one-to-many style sockets, the effect is the same, except that it
+ applies to one or all associations (see Section 3.3) bound to the
+ socket descriptor used in the setsockopt() or getsockopt() call. The
+ option applies to each association's window size separately. This
+ option expects an integer.
+
+ Note that this is a socket-level option, not an SCTP-level option.
+ When using this option, an application must specify a level of
+ SOL_SOCKET in the call.
+
+8.1.8. Automatic Close of Associations (SCTP_AUTOCLOSE)
+
+ This socket option is applicable to the one-to-many style socket
+ only. When set, it will cause associations that are idle for more
+ than the specified number of seconds to automatically close using the
+ graceful shutdown procedure. An idle association is defined as an
+ association that has not sent or received user data. The special
+ value of '0' indicates that no automatic close of any association
+ should be performed; this is the default value. This option expects
+ an integer defining the number of seconds of idle time before an
+ association is closed.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 67]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ An application using this option should enable the ability to receive
+ the association change notification. This is the only mechanism by
+ which an application is informed about the closing of an association.
+ After an association is closed, the association identifier assigned
+ to it can be reused. An application should be aware of this to avoid
+ the possible problem of sending data to an incorrect peer endpoint.
+
+8.1.9. Set Primary Address (SCTP_PRIMARY_ADDR)
+
+ This option requests that the local SCTP stack uses the enclosed peer
+ address as the association's primary. The enclosed address must be
+ one of the association peer's addresses.
+
+ The following structure is used to make a set peer primary request:
+
+ struct sctp_setprim {
+ sctp_assoc_t ssp_assoc_id;
+ struct sockaddr_storage ssp_addr;
+ };
+
+ ssp_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, it identifies the
+ association for this request. Note that the special sctp_assoc_t
+ SCTP_{FUTURE|ALL|CURRENT}_ASSOC are not allowed.
+
+ ssp_addr: This parameter is the address to set as primary. No
+ wildcard address is allowed.
+
+8.1.10. Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
+
+ This option requests that the local endpoint set the specified
+ Adaptation Layer Indication parameter for all future INIT and
+ INIT-ACK exchanges.
+
+ The following structure is used to access and modify this parameter:
+
+ struct sctp_setadaptation {
+ uint32_t ssb_adaptation_ind;
+ };
+
+ ssb_adaptation_ind: The adaptation layer indicator that will be
+ included in any outgoing Adaptation Layer Indication parameter.
+
+8.1.11. Enable/Disable Message Fragmentation (SCTP_DISABLE_FRAGMENTS)
+
+ This option is an on/off flag and is passed as an integer, where a
+ non-zero is on and a zero is off. If enabled, no SCTP message
+ fragmentation will be performed. The effect of enabling this option
+
+
+
+Stewart, et al. Informational [Page 68]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ is that if a message being sent exceeds the current Path MTU (PMTU)
+ size, the message will not be sent and instead an error will be
+ indicated to the user. If this option is disabled (the default),
+ then a message exceeding the size of the PMTU will be fragmented and
+ reassembled by the peer.
+
+8.1.12. Peer Address Parameters (SCTP_PEER_ADDR_PARAMS)
+
+ Applications can enable or disable heartbeats for any peer address of
+ an association, modify an address's heartbeat interval, force a
+ heartbeat to be sent immediately, and adjust the address's maximum
+ number of retransmissions sent before an address is considered
+ unreachable.
+
+ The following structure is used to access and modify an address's
+ parameters:
+
+ struct sctp_paddrparams {
+ sctp_assoc_t spp_assoc_id;
+ struct sockaddr_storage spp_address;
+ uint32_t spp_hbinterval;
+ uint16_t spp_pathmaxrxt;
+ uint32_t spp_pathmtu;
+ uint32_t spp_flags;
+ uint32_t spp_ipv6_flowlabel;
+ uint8_t spp_dscp;
+ };
+
+ spp_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, the application may fill
+ in an association identifier or SCTP_FUTURE_ASSOC for this query.
+ It is an error to use SCTP_{CURRENT|ALL}_ASSOC in spp_assoc_id.
+
+ spp_address: This specifies which address is of interest. If a
+ wildcard address is provided, it applies to all current and future
+ paths.
+
+ spp_hbinterval: This contains the value of the heartbeat interval,
+ in milliseconds (HB.Interval in [RFC4960]). Note that unless the
+ spp_flags field is set to SPP_HB_ENABLE, the value of this field
+ is ignored. Note also that a value of zero indicates that the
+ current setting should be left unchanged. To set an actual value
+ of zero, the SPP_HB_TIME_IS_ZERO flag should be used. Even when
+ it is set to 0, it does not mean that SCTP will continuously send
+ out heartbeats, since the actual interval also includes the
+ current RTO and jitter (see Section 8.3 of [RFC4960]).
+
+
+
+
+
+Stewart, et al. Informational [Page 69]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ spp_pathmaxrxt: This contains the maximum number of retransmissions
+ before this address shall be considered unreachable. Note that a
+ value of zero indicates that the current setting should be left
+ unchanged.
+
+ spp_pathmtu: This field contains the current Path MTU of the peer
+ address. It is the number of bytes available in an SCTP packet
+ for chunks. Providing a value of 0 does not change the current
+ setting. If a positive value is provided and SPP_PMTUD_DISABLE is
+ set in the spp_flags field, the given value is used as the Path
+ MTU. If SPP_PMTUD_ENABLE is set in the spp_flags field, the
+ spp_pathmtu field is ignored.
+
+ spp_flags: These flags are used to control various features on an
+ association. The flag field is a bitmask that may contain zero or
+ more of the following options:
+
+ SPP_HB_ENABLE: This field enables heartbeats on the specified
+ address.
+
+ SPP_HB_DISABLE: This field disables heartbeats on the specified
+ address. Note that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ mutually exclusive; only one of these two should be specified.
+ Enabling both fields will yield undetermined results.
+
+ SPP_HB_DEMAND: This field requests that a user-initiated
+ heartbeat be made immediately. This must not be used in
+ conjunction with a wildcard address.
+
+ SPP_HB_TIME_IS_ZERO: This field specifies that the time for
+ heartbeat delay is to be set to 0 milliseconds.
+
+ SPP_PMTUD_ENABLE: This field will enable PMTU discovery on the
+ specified address.
+
+ SPP_PMTUD_DISABLE: This field will disable PMTU discovery on the
+ specified address. Note that if the address field is empty,
+ then all addresses on the association are affected. Note also
+ that SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ exclusive. Enabling both fields will yield undetermined
+ results.
+
+ SPP_IPV6_FLOWLABEL: Setting this flag enables the setting of the
+ IPV6 flow label value. The value is contained in the
+ spp_ipv6_flowlabel field.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 70]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Upon retrieval, this flag will be set to indicate that the
+ spp_ipv6_flowlabel field has a valid value returned. If a
+ specific destination address is set (in the spp_address field),
+ then the value returned is that of the address. If just an
+ association is specified (and no address), then the
+ association's default flow label is returned. If neither an
+ association nor a destination is specified, then the socket's
+ default flow label is returned. For non-IPv6 sockets, this
+ flag will be left cleared.
+
+ SPP_DSCP: Setting this flag enables the setting of the
+ Differentiated Services Code Point (DSCP) value associated with
+ either the association or a specific address. The value is
+ obtained in the spp_dscp field.
+
+ Upon retrieval, this flag will be set to indicate that the
+ spp_dscp field has a valid value returned. If a specific
+ destination address is set when called (in the spp_address
+ field), then that specific destination address's DSCP value is
+ returned. If just an association is specified, then the
+ association's default DSCP is returned. If neither an
+ association nor a destination is specified, then the socket's
+ default DSCP is returned.
+
+ spp_ipv6_flowlabel: This field is used in conjunction with the
+ SPP_IPV6_FLOWLABEL flag and contains the IPv6 flow label. The 20
+ least significant bits are used for the flow label. This setting
+ has precedence over any IPv6-layer setting.
+
+ spp_dscp: This field is used in conjunction with the SPP_DSCP flag
+ and contains the DSCP. The 6 most significant bits are used for
+ the DSCP. This setting has precedence over any IPv4- or IPv6-
+ layer setting.
+
+ Please note that changing the flow label or DSCP value will affect
+ all packets sent by the SCTP stack after setting these parameters.
+ The flow label might also be set via the sin6_flowinfo field of the
+ sockaddr_in6 structure.
+
+8.1.13. Set Default Send Parameters (SCTP_DEFAULT_SEND_PARAM) -
+ DEPRECATED
+
+ Please note that this option is deprecated. SCTP_DEFAULT_SNDINFO
+ (Section 8.1.31) should be used instead.
+
+ Applications that wish to use the sendto() system call may wish to
+ specify a default set of parameters that would normally be supplied
+ through the inclusion of ancillary data. This socket option allows
+
+
+
+Stewart, et al. Informational [Page 71]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ such an application to set the default sctp_sndrcvinfo structure.
+ The application that wishes to use this socket option simply passes
+ the sctp_sndrcvinfo structure (defined in Section 5.3.2) to this
+ call. The input parameters accepted by this call include
+ sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, and
+ sinfo_timetolive. The sinfo_flags field is composed of a bitwise OR
+ of SCTP_UNORDERED, SCTP_EOF, and SCTP_SENDALL. The sinfo_assoc_id
+ field specifies the association to which to apply the parameters.
+ For a one-to-many style socket, any of the predefined constants are
+ also allowed in this field. The field is ignored for one-to-one
+ style sockets.
+
+8.1.14. Set Notification and Ancillary Events (SCTP_EVENTS) -
+ DEPRECATED
+
+ This socket option is used to specify various notifications and
+ ancillary data the user wishes to receive. Please see Section 6.2.1
+ for a full description of this option and its usage. Note that this
+ option is considered deprecated and is present for backward
+ compatibility. New applications should use the SCTP_EVENT option.
+ See Section 6.2.2 for a full description of that option as well.
+
+8.1.15. Set/Clear IPv4 Mapped Addresses (SCTP_I_WANT_MAPPED_V4_ADDR)
+
+ This socket option is a boolean flag that turns on or off the mapping
+ of IPv4 addresses. If this option is turned on, then IPv4 addresses
+ will be mapped to IPv6 representation. If this option is turned off,
+ then no mapping will be done of IPv4 addresses, and a user will
+ receive both PF_INET6 and PF_INET type addresses on the socket. See
+ [RFC3542] for more details on mapped IPv6 addresses.
+
+ If this socket option is used on a socket of type PF_INET, an error
+ is returned.
+
+ By default, this option is turned off and expects an integer to be
+ passed where a non-zero value turns on the option and a zero value
+ turns off the option.
+
+8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
+
+ This option will get or set the maximum size to put in any outgoing
+ SCTP DATA chunk. If a message is larger than this maximum size, it
+ will be fragmented by SCTP into the specified size. Note that the
+ underlying SCTP implementation may fragment into smaller sized chunks
+ when the PMTU of the underlying association is smaller than the value
+ set by the user. The default value for this option is '0', which
+ indicates that the user is not limiting fragmentation and only the
+ PMTU will affect SCTP's choice of DATA chunk size. Note also that
+
+
+
+Stewart, et al. Informational [Page 72]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ values set larger than the maximum size of an IP datagram will
+ effectively let SCTP control fragmentation (i.e., the same as setting
+ this option to 0).
+
+ The following structure is used to access and modify this parameter:
+
+ struct sctp_assoc_value {
+ sctp_assoc_t assoc_id;
+ uint32_t assoc_value;
+ };
+
+ assoc_id: This parameter is ignored for one-to-one style sockets.
+ For one-to-many style sockets, this parameter indicates upon which
+ association the user is performing an action. It is an error to
+ use SCTP_{CURRENT|ALL}_ASSOC in assoc_id.
+
+ assoc_value: This parameter specifies the maximum size in bytes.
+
+8.1.17. Get or Set the List of Supported HMAC Identifiers
+ (SCTP_HMAC_IDENT)
+
+ This option gets or sets the list of Hashed Message Authentication
+ Code (HMAC) algorithms that the local endpoint requires the peer
+ to use.
+
+ The following structure is used to get or set these identifiers:
+
+ struct sctp_hmacalgo {
+ uint32_t shmac_number_of_idents;
+ uint16_t shmac_idents[];
+ };
+
+ shmac_number_of_idents: This field gives the number of elements
+ present in the array shmac_idents.
+
+ shmac_idents: This parameter contains an array of HMAC identifiers
+ that the local endpoint is requesting the peer to use, in priority
+ order. The following identifiers are valid:
+
+ * SCTP_AUTH_HMAC_ID_SHA1
+
+ * SCTP_AUTH_HMAC_ID_SHA256
+
+ Note that the list supplied must include SCTP_AUTH_HMAC_ID_SHA1 and
+ may include any of the other values in its preferred order (lowest
+ list position has the highest preference in algorithm selection).
+
+
+
+
+
+Stewart, et al. Informational [Page 73]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Note also that the lack of SCTP_AUTH_HMAC_ID_SHA1, or the inclusion
+ of an unknown HMAC identifier (including optional identifiers unknown
+ to the implementation), will cause the set option to fail and return
+ an error.
+
+8.1.18. Get or Set the Active Shared Key (SCTP_AUTH_ACTIVE_KEY)
+
+ This option will get or set the active shared key to be used to build
+ the association shared key.
+
+ The following structure is used to access and modify these
+ parameters:
+
+ struct sctp_authkeyid {
+ sctp_assoc_t scact_assoc_id;
+ uint16_t scact_keynumber;
+ };
+
+ scact_assoc_id: This parameter sets the active key of the specified
+ association. The special SCTP_{FUTURE|CURRENT|ALL}_ASSOC can be
+ used. For one-to-one style sockets, this parameter is ignored.
+ Note, however, that this option will set the active key on the
+ association if the socket is connected; otherwise, this option
+ will set the default active key for the endpoint.
+
+ scact_keynumber: This parameter is the shared key identifier that
+ the application is requesting to become the active shared key to
+ be used for sending authenticated chunks. The key identifier must
+ correspond to an existing shared key. Note that shared key
+ identifier '0' defaults to a null key.
+
+ When used with setsockopt(), the SCTP implementation must use the
+ indicated shared key identifier for all messages being given to an
+ SCTP implementation via a send call after the setsockopt() call,
+ until changed again. Therefore, the SCTP implementation must not
+ bundle user messages that should be authenticated using different
+ shared key identifiers.
+
+ Initially, the key with key identifier 0 is the active key.
+
+8.1.19. Get or Set Delayed SACK Timer (SCTP_DELAYED_SACK)
+
+ This option will affect the way delayed SACKs are performed. This
+ option allows the application to get or set the delayed SACK time, in
+ milliseconds. It also allows changing the delayed SACK frequency.
+ Changing the frequency to 1 disables the delayed SACK algorithm.
+ Note that if sack_delay or sack_freq is 0 when setting this option,
+ the current values will remain unchanged.
+
+
+
+Stewart, et al. Informational [Page 74]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The following structure is used to access and modify these
+ parameters:
+
+ struct sctp_sack_info {
+ sctp_assoc_t sack_assoc_id;
+ uint32_t sack_delay;
+ uint32_t sack_freq;
+ };
+
+ sack_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, this parameter indicates
+ upon which association the user is performing an action. The
+ special SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+ sack_delay: This parameter contains the number of milliseconds the
+ user is requesting that the delayed SACK timer be set to. Note
+ that this value is defined in [RFC4960] to be between 200 and 500
+ milliseconds.
+
+ sack_freq: This parameter contains the number of packets that must
+ be received before a SACK is sent without waiting for the delay
+ timer to expire. The default value is 2; setting this value to 1
+ will disable the delayed SACK algorithm.
+
+8.1.20. Get or Set Fragmented Interleave (SCTP_FRAGMENT_INTERLEAVE)
+
+ Fragmented interleave controls how the presentation of messages
+ occurs for the message receiver. There are three levels of fragment
+ interleave defined. Two of the levels affect one-to-one style
+ sockets, while one-to-many style sockets are affected by all three
+ levels.
+
+ This option takes an integer value. It can be set to a value of 0,
+ 1, or 2. Attempting to set this level to other values will return an
+ error.
+
+ Setting the three levels provides the following receiver
+ interactions:
+
+ level 0: Prevents the interleaving of any messages. This means that
+ when a partial delivery begins, no other messages will be received
+ except the message being partially delivered. If another message
+ arrives on a different stream (or association) that could be
+ delivered, it will be blocked waiting for the user to read all of
+ the partially delivered message.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 75]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ level 1: Allows interleaving of messages that are from different
+ associations. For one-to-one style sockets, level 0 and level 1
+ thus have the same meaning, since a one-to-one style socket always
+ receives messages from the same association. Note that setting a
+ one-to-many style socket to this level may cause multiple partial
+ deliveries from different associations, but for any given
+ association, only one message will be delivered until all parts of
+ a message have been delivered. This means that one large message,
+ being read with an association identifier of "X", will block other
+ messages from association "X" from being delivered.
+
+ level 2: Allows complete interleaving of messages. This level
+ requires that the sender not only carefully observe the peer
+ association identifier (or address) but also pay careful attention
+ to the stream number. With this option enabled, a partially
+ delivered message may begin being delivered for association "X"
+ stream "Y", and the next subsequent receive may return a message
+ from association "X" stream "Z". Note that no other messages
+ would be delivered for association "X" stream "Y" until all of
+ stream "Y"'s partially delivered message was read. Note that this
+ option also affects one-to-one style sockets. Also note that for
+ one-to-many style sockets, not only another stream's message from
+ the same association may be delivered upon the next receive, but
+ some other association's message may also be delivered upon the
+ next receive.
+
+ An implementation should default one-to-many style sockets to level
+ 1, because otherwise, it is possible that a peer could begin sending
+ a partial message and thus block all other peers from sending data.
+ However, a setting of level 2 requires that the application not only
+ be aware of the association (via the association identifier or peer's
+ address) but also the stream number. The stream number is not
+ present unless the user has subscribed to the sctp_data_io_event (see
+ Section 6.2), which is deprecated, or has enabled the
+ SCTP_RECVRCVINFO socket option (see Section 8.1.29). This is also
+ why we recommend that one-to-one style sockets be defaulted to level
+ 0 (level 1 for one-to-one style sockets has no effect). Note that an
+ implementation should return an error if an application attempts to
+ set the level to 2 and has not subscribed to the sctp_data_io_event
+ event, which is deprecated, or has enabled the SCTP_RECVRCVINFO
+ socket option.
+
+ For applications that have subscribed to events, those events appear
+ in the normal socket buffer data stream. This means that unless the
+ user has set the fragmentation interleave level to 0, notifications
+ may also be interleaved with partially delivered messages.
+
+
+
+
+
+Stewart, et al. Informational [Page 76]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.1.21. Set or Get the SCTP Partial Delivery Point
+ (SCTP_PARTIAL_DELIVERY_POINT)
+
+ This option will set or get the SCTP partial delivery point. This
+ point is the size of a message where the partial delivery API will be
+ invoked to help free up rwnd space for the peer. Setting this to a
+ lower value will cause partial deliveries to happen more often. This
+ option expects an integer that sets or gets the partial delivery
+ point in bytes. Note also that the call will fail if the user
+ attempts to set this value larger than the socket receive buffer
+ size.
+
+ Note that any single message having a length smaller than or equal to
+ the SCTP partial delivery point will be delivered in a single read
+ call as long as the user-provided buffer is large enough to hold the
+ message.
+
+8.1.22. Set or Get the Use of Extended Receive Info
+ (SCTP_USE_EXT_RCVINFO) - DEPRECATED
+
+ This option will enable or disable the use of the extended version of
+ the sctp_sndrcvinfo structure. If this option is disabled, then the
+ normal sctp_sndrcvinfo structure is returned in all receive message
+ calls. If this option is enabled, then the sctp_extrcvinfo structure
+ is returned in all receive message calls. The default is off.
+
+ Note that the sctp_extrcvinfo structure is never used in any send
+ call.
+
+ This option is present for compatibility with older applications and
+ is deprecated. Future applications should use SCTP_NXTINFO to
+ retrieve this same information via ancillary data.
+
+8.1.23. Set or Get the Auto ASCONF Flag (SCTP_AUTO_ASCONF)
+
+ This option will enable or disable the use of the automatic
+ generation of ASCONF chunks to add and delete addresses to an
+ existing association. Note that this option has two caveats, namely
+ a) it only affects sockets that are bound to all addresses available
+ to the SCTP stack, and b) the system administrator may have an
+ overriding control that turns the ASCONF feature off no matter what
+ setting the socket option may have.
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+
+
+
+
+
+Stewart, et al. Informational [Page 77]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.1.24. Set or Get the Maximum Burst (SCTP_MAX_BURST)
+
+ This option will allow a user to change the maximum burst of packets
+ that can be emitted by this association. Note that the default value
+ is 4, and some implementations may restrict this setting so that it
+ can only be lowered to positive values.
+
+ To set or get this option, the user fills in the following structure:
+
+ struct sctp_assoc_value {
+ sctp_assoc_t assoc_id;
+ uint32_t assoc_value;
+ };
+
+ assoc_id: This parameter is ignored for one-to-one style sockets.
+ For one-to-many style sockets, this parameter indicates upon which
+ association the user is performing an action. The special
+ SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+ assoc_value: This parameter contains the maximum burst. Setting the
+ value to 0 disables burst mitigation.
+
+8.1.25. Set or Get the Default Context (SCTP_CONTEXT)
+
+ The context field in the sctp_sndrcvinfo structure is normally only
+ used when a failed message is retrieved holding the value that was
+ sent down on the actual send call. This option allows the setting,
+ on an association basis, of a default context that will be received
+ on reading messages from the peer. This is especially helpful for an
+ application when using one-to-many style sockets to keep some
+ reference to an internal state machine that is processing messages on
+ the association. Note that the setting of this value only affects
+ received messages from the peer and does not affect the value that is
+ saved with outbound messages.
+
+ To set or get this option, the user fills in the following structure:
+
+ struct sctp_assoc_value {
+ sctp_assoc_t assoc_id;
+ uint32_t assoc_value;
+ };
+
+ assoc_id: This parameter is ignored for one-to-one style sockets.
+ For one-to-many style sockets, this parameter indicates upon which
+ association the user is performing an action. The special
+ SCTP_{FUTURE|CURRENT|ALL}_ASSOC can also be used.
+
+ assoc_value: This parameter contains the context.
+
+
+
+Stewart, et al. Informational [Page 78]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.1.26. Enable or Disable Explicit EOR Marking (SCTP_EXPLICIT_EOR)
+
+ This boolean flag is used to enable or disable explicit end of record
+ (EOR) marking. When this option is enabled, a user may make multiple
+ send system calls to send a record and must indicate that they are
+ finished sending a particular record by including the SCTP_EOR flag.
+ If this boolean flag is disabled, then each individual send system
+ call is considered to have an SCTP_EOR indicator set on it implicitly
+ without the user having to explicitly add this flag. The default
+ is off.
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+8.1.27. Enable SCTP Port Reusage (SCTP_REUSE_PORT)
+
+ This option only supports one-to-one style SCTP sockets. If used on
+ a one-to-many style SCTP socket, an error is indicated.
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+ This socket option must not be used after calling bind() or
+ sctp_bindx() for a one-to-one style SCTP socket. If using bind() or
+ sctp_bindx() on a socket with the SCTP_REUSE_PORT option, all other
+ SCTP sockets bound to the same port must have set the SCTP_REUSE_PORT
+ option. Calling bind() or sctp_bindx() for a socket without having
+ set the SCTP_REUSE_PORT option will fail if there are other sockets
+ bound to the same port. At most one socket being bound to the same
+ port may be listening.
+
+ It should be noted that the behavior of the socket-level socket
+ option to reuse ports and/or addresses for SCTP sockets is
+ unspecified.
+
+8.1.28. Set Notification Event (SCTP_EVENT)
+
+ This socket option is used to set a specific notification option.
+ Please see Section 6.2.2 for a full description of this option and
+ its usage.
+
+8.1.29. Enable or Disable the Delivery of SCTP_RCVINFO as Ancillary
+ Data (SCTP_RECVRCVINFO)
+
+ Setting this option specifies that SCTP_RCVINFO (defined in
+ Section 5.3.5) is returned as ancillary data by recvmsg().
+
+
+
+
+
+Stewart, et al. Informational [Page 79]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+8.1.30. Enable or Disable the Delivery of SCTP_NXTINFO as Ancillary
+ Data (SCTP_RECVNXTINFO)
+
+ Setting this option specifies that SCTP_NXTINFO (defined in
+ Section 5.3.6) is returned as ancillary data by recvmsg().
+
+ This option expects an integer boolean flag, where a non-zero value
+ turns on the option, and a zero value turns off the option.
+
+8.1.31. Set Default Send Parameters (SCTP_DEFAULT_SNDINFO)
+
+ Applications that wish to use the sendto() system call may wish to
+ specify a default set of parameters that would normally be supplied
+ through the inclusion of ancillary data. This socket option allows
+ such an application to set the default sctp_sndinfo structure. The
+ application that wishes to use this socket option simply passes the
+ sctp_sndinfo structure (defined in Section 5.3.4) to this call. The
+ input parameters accepted by this call include snd_sid, snd_flags,
+ snd_ppid, and snd_context. The snd_flags parameter is composed of a
+ bitwise OR of SCTP_UNORDERED, SCTP_EOF, and SCTP_SENDALL. The
+ snd_assoc_id field specifies the association to which to apply the
+ parameters. For a one-to-many style socket, any of the predefined
+ constants are also allowed in this field. The field is ignored for
+ one-to-one style sockets.
+
+8.1.32. Set Default PR-SCTP Parameters (SCTP_DEFAULT_PRINFO)
+
+ This option sets and gets the default parameters for PR-SCTP. They
+ can be overwritten by specific information provided in send calls.
+
+ The following structure is used to access and modify these
+ parameters:
+
+ struct sctp_default_prinfo {
+ uint16_t pr_policy;
+ uint32_t pr_value;
+ sctp_assoc_t pr_assoc_id;
+ };
+
+ pr_policy: This field is the same as that described in
+ Section 5.3.7.
+
+ pr_value: This field is the same as that described in Section 5.3.7.
+
+
+
+
+
+Stewart, et al. Informational [Page 80]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ pr_assoc_id: This field is ignored for one-to-one style sockets.
+ For one-to-many style sockets, pr_assoc_id can be a particular
+ association identifier or SCTP_{FUTURE|CURRENT|ALL}_ASSOC.
+
+8.2. Read-Only Options
+
+ The options defined in this subsection are read-only. Using this
+ option in a setsockopt() call will result in an error indicating
+ EOPNOTSUPP.
+
+8.2.1. Association Status (SCTP_STATUS)
+
+ Applications can retrieve current status information about an
+ association, including association state, peer receiver window size,
+ number of unacknowledged DATA chunks, and number of DATA chunks
+ pending receipt. This information is read-only.
+
+ The following structure is used to access this information:
+
+ struct sctp_status {
+ sctp_assoc_t sstat_assoc_id;
+ int32_t sstat_state;
+ uint32_t sstat_rwnd;
+ uint16_t sstat_unackdata;
+ uint16_t sstat_penddata;
+ uint16_t sstat_instrms;
+ uint16_t sstat_outstrms;
+ uint32_t sstat_fragmentation_point;
+ struct sctp_paddrinfo sstat_primary;
+ };
+
+ sstat_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, it holds the identifier
+ for the association. All notifications for a given association
+ have the same association identifier. The special SCTP_{FUTURE|
+ CURRENT|ALL}_ASSOC cannot be used.
+
+ sstat_state: This contains the association's current state, i.e.,
+ one of the following values:
+
+ * SCTP_CLOSED
+
+ * SCTP_BOUND
+
+ * SCTP_LISTEN
+
+ * SCTP_COOKIE_WAIT
+
+
+
+
+Stewart, et al. Informational [Page 81]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ * SCTP_COOKIE_ECHOED
+
+ * SCTP_ESTABLISHED
+
+ * SCTP_SHUTDOWN_PENDING
+
+ * SCTP_SHUTDOWN_SENT
+
+ * SCTP_SHUTDOWN_RECEIVED
+
+ * SCTP_SHUTDOWN_ACK_SENT
+
+ sstat_rwnd: This contains the association peer's current receiver
+ window size.
+
+ sstat_unackdata: This is the number of unacknowledged DATA chunks.
+
+ sstat_penddata: This is the number of DATA chunks pending receipt.
+
+ sstat_instrms: This is the number of streams that the peer will be
+ using outbound.
+
+ sstat_outstrms: This is the number of outbound streams that the
+ endpoint is allowed to use.
+
+ sstat_fragmentation_point: This is the size at which SCTP
+ fragmentation will occur.
+
+ sstat_primary: This is information on the current primary peer
+ address.
+
+ To access these status values, the application calls getsockopt()
+ with the option name SCTP_STATUS.
+
+8.2.2. Peer Address Information (SCTP_GET_PEER_ADDR_INFO)
+
+ Applications can retrieve information about a specific peer address
+ of an association, including its reachability state, congestion
+ window, and retransmission timer values. This information is
+ read-only.
+
+ The following structure is used to access this information:
+
+ struct sctp_paddrinfo {
+ sctp_assoc_t spinfo_assoc_id;
+ struct sockaddr_storage spinfo_address;
+ int32_t spinfo_state;
+ uint32_t spinfo_cwnd;
+
+
+
+Stewart, et al. Informational [Page 82]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ uint32_t spinfo_srtt;
+ uint32_t spinfo_rto;
+ uint32_t spinfo_mtu;
+ };
+
+ spinfo_assoc_id: This parameter is ignored for one-to-one style
+ sockets.
+
+ For one-to-many style sockets, this field may be filled by the
+ application, and if so, this field will have priority in looking
+ up the association instead of using the address specified in
+ spinfo_address. Note that if the address does not belong to the
+ association specified, then this call will fail. If the
+ application does not fill in the spinfo_assoc_id, then the address
+ will be used to look up the association, and on return, this field
+ will have the valid association identifier. In other words, this
+ call can be used to translate an address into an association
+ identifier. Note that the predefined constants are not allowed
+ for this option.
+
+ spinfo_address: This is filled by the application and contains the
+ peer address of interest.
+
+ spinfo_state: This contains the peer address's state:
+
+ SCTP_UNCONFIRMED: This is the initial state of a peer address.
+
+ SCTP_ACTIVE: This state is entered the first time after path
+ verification. It can also be entered if the state is
+ SCTP_INACTIVE and the path supervision detects that the peer
+ address is reachable again.
+
+ SCTP_INACTIVE: This state is entered whenever a path failure is
+ detected.
+
+ spinfo_cwnd: This contains the peer address's current congestion
+ window.
+
+ spinfo_srtt: This contains the peer address's current smoothed
+ round-trip time calculation in milliseconds.
+
+ spinfo_rto: This contains the peer address's current retransmission
+ timeout value in milliseconds.
+
+ spinfo_mtu: This is the current Path MTU of the peer address. It is
+ the number of bytes available in an SCTP packet for chunks.
+
+
+
+
+
+Stewart, et al. Informational [Page 83]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.2.3. Get the List of Chunks the Peer Requires to Be Authenticated
+ (SCTP_PEER_AUTH_CHUNKS)
+
+ This option gets a list of chunk types (see [RFC4960]) for a
+ specified association that the peer requires to be received
+ authenticated only.
+
+ The following structure is used to access these parameters:
+
+ struct sctp_authchunks {
+ sctp_assoc_t gauth_assoc_id;
+ uint32_t gauth_number_of_chunks
+ uint8_t gauth_chunks[];
+ };
+
+ gauth_assoc_id: This parameter indicates for which association the
+ user is requesting the list of peer-authenticated chunks. For
+ one-to-one style sockets, this parameter is ignored. Note that
+ the predefined constants are not allowed with this option.
+
+ gauth_number_of_chunks: This parameter gives the number of elements
+ in the array gauth_chunks.
+
+ gauth_chunks: This parameter contains an array of chunk types that
+ the peer is requesting to be authenticated. If the passed-in
+ buffer size is not large enough to hold the list of chunk types,
+ ENOBUFS is returned.
+
+8.2.4. Get the List of Chunks the Local Endpoint Requires to Be
+ Authenticated (SCTP_LOCAL_AUTH_CHUNKS)
+
+ This option gets a list of chunk types (see [RFC4960]) for a
+ specified association that the local endpoint requires to be received
+ authenticated only.
+
+ The following structure is used to access these parameters:
+
+ struct sctp_authchunks {
+ sctp_assoc_t gauth_assoc_id;
+ uint32_t gauth_number_of_chunks;
+ uint8_t gauth_chunks[];
+ };
+
+ gauth_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, the application may fill
+ in an association identifier or SCTP_FUTURE_ASSOC. It is an error
+ to use SCTP_{CURRENT|ALL}_ASSOC in gauth_assoc_id.
+
+
+
+
+Stewart, et al. Informational [Page 84]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ gauth_number_of_chunks: This parameter gives the number of elements
+ in the array gauth_chunks.
+
+ gauth_chunks: This parameter contains an array of chunk types that
+ the local endpoint is requesting to be authenticated. If the
+ passed-in buffer is not large enough to hold the list of chunk
+ types, ENOBUFS is returned.
+
+8.2.5. Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)
+
+ This option gets the current number of associations that are attached
+ to a one-to-many style socket. The option value is an uint32_t.
+ Note that this number is only a snapshot. This means that the number
+ of associations may have changed when the caller gets back the option
+ result.
+
+ For a one-to-one style socket, this socket option results in an
+ error.
+
+8.2.6. Get the Current Identifiers of Associations
+ (SCTP_GET_ASSOC_ID_LIST)
+
+ This option gets the current list of SCTP association identifiers of
+ the SCTP associations handled by a one-to-many style socket.
+
+ The option value has the structure
+
+ struct sctp_assoc_ids {
+ uint32_t gaids_number_of_ids;
+ sctp_assoc_t gaids_assoc_id[];
+ };
+
+ The caller must provide a large enough buffer to hold all association
+ identifiers. If the buffer is too small, an error must be returned.
+ The user can use the SCTP_GET_ASSOC_NUMBER socket option to get an
+ idea of how large the buffer has to be. gaids_number_of_ids gives
+ the number of elements in the array gaids_assoc_id. Note also that
+ some or all of sctp_assoc_t returned in the array may become invalid
+ by the time the caller gets back the result.
+
+ For a one-to-one style socket, this socket option results in an
+ error.
+
+8.3. Write-Only Options
+
+ The options defined in this subsection are write-only. Using this
+ option in a getsockopt() or sctp_opt_info() call will result in an
+ error indicating EOPNOTSUPP.
+
+
+
+Stewart, et al. Informational [Page 85]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+8.3.1. Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+
+ This call requests that the peer mark the enclosed address as the
+ association primary (see [RFC5061]). The enclosed address must be
+ one of the association's locally bound addresses.
+
+ The following structure is used to make a set peer primary request:
+
+ struct sctp_setpeerprim {
+ sctp_assoc_t sspp_assoc_id;
+ struct sockaddr_storage sspp_addr;
+ };
+
+ sspp_assoc_id: This parameter is ignored for one-to-one style
+ sockets. For one-to-many style sockets, it identifies the
+ association for this request. Note that the predefined constants
+ are not allowed for this option.
+
+ sspp_addr: The address to set as primary.
+
+8.3.2. Add a Chunk That Must Be Authenticated (SCTP_AUTH_CHUNK)
+
+ This set option adds a chunk type that the user is requesting to be
+ received only in an authenticated way. Changes to the list of chunks
+ will only affect future associations on the socket.
+
+ The following structure is used to add a chunk:
+
+ struct sctp_authchunk {
+ uint8_t sauth_chunk;
+ };
+
+ sauth_chunk: This parameter contains a chunk type that the user is
+ requesting to be authenticated.
+
+ The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE, and AUTH
+ chunks must not be used. If they are used, an error must be
+ returned. The usage of this option enables SCTP AUTH in cases where
+ it is not required by other means (for example, the use of dynamic
+ address reconfiguration).
+
+8.3.3. Set a Shared Key (SCTP_AUTH_KEY)
+
+ This option will set a shared secret key that is used to build an
+ association shared key.
+
+ The following structure is used to access and modify these
+ parameters:
+
+
+
+Stewart, et al. Informational [Page 86]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ struct sctp_authkey {
+ sctp_assoc_t sca_assoc_id;
+ uint16_t sca_keynumber;
+ uint16_t sca_keylength;
+ uint8_t sca_key[];
+ };
+
+ sca_assoc_id: This parameter indicates on what association the
+ shared key is being set. The special SCTP_{FUTURE|CURRENT|
+ ALL}_ASSOC can be used. For one-to-one style sockets, this
+ parameter is ignored. Note, however, that on one-to-one style
+ sockets, this option will set a key on the association if the
+ socket is connected; otherwise, this option will set a key on the
+ endpoint.
+
+ sca_keynumber: This parameter is the shared key identifier by which
+ the application will refer to this shared key. If a key of the
+ specified index already exists, then this new key will replace the
+ old existing key. Note that shared key identifier '0' defaults to
+ a null key.
+
+ sca_keylength: This parameter is the length of the array sca_key.
+
+ sca_key: This parameter contains an array of bytes that is to be
+ used by the endpoint (or association) as the shared secret key.
+ Note that if the length of this field is zero, a null key is set.
+
+8.3.4. Deactivate a Shared Key (SCTP_AUTH_DEACTIVATE_KEY)
+
+ This set option indicates that the application will no longer send
+ user messages using the indicated key identifier.
+
+ struct sctp_authkeyid {
+ sctp_assoc_t scact_assoc_id;
+ uint16_t scact_keynumber;
+ };
+
+ scact_assoc_id: This parameter indicates from which association the
+ shared key identifier is being deleted. The special SCTP_{FUTURE|
+ CURRENT|ALL}_ASSOC can be used. For one-to-one style sockets,
+ this parameter is ignored. Note, however, that this option will
+ deactivate the key from the association if the socket is
+ connected; otherwise, this option will deactivate the key from the
+ endpoint.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 87]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ scact_keynumber: This parameter is the shared key identifier that
+ the application is requesting to be deactivated. The key
+ identifier must correspond to an existing shared key. Note that
+ if this parameter is zero, use of the null key identifier '0' is
+ deactivated on the endpoint and/or association.
+
+ The currently active key cannot be deactivated.
+
+8.3.5. Delete a Shared Key (SCTP_AUTH_DELETE_KEY)
+
+ This set option will delete an SCTP association's shared secret key
+ that has been deactivated.
+
+ struct sctp_authkeyid {
+ sctp_assoc_t scact_assoc_id;
+ uint16_t scact_keynumber;
+ };
+
+ scact_assoc_id: This parameter indicates from which association the
+ shared key identifier is being deleted. The special SCTP_{FUTURE|
+ CURRENT|ALL}_ASSOC can be used. For one-to-one style sockets,
+ this parameter is ignored. Note, however, that this option will
+ delete the key from the association if the socket is connected;
+ otherwise, this option will delete the key from the endpoint.
+
+ scact_keynumber: This parameter is the shared key identifier that
+ the application is requesting to be deleted. The key identifier
+ must correspond to an existing shared key and must not be in use
+ for any packet being sent by the SCTP implementation. This means,
+ in particular, that it must be deactivated first. Note that if
+ this parameter is zero, use of the null key identifier '0' is
+ deleted from the endpoint and/or association.
+
+ Only deactivated keys that are no longer used by an association can
+ be deleted.
+
+9. New Functions
+
+ Depending on the system, the following interface can be implemented
+ as a system call or library function.
+
+9.1. sctp_bindx()
+
+ This function allows the user to bind a specific subset of addresses
+ or, if the SCTP extension described in [RFC5061] is supported, add or
+ delete specific addresses.
+
+
+
+
+
+Stewart, et al. Informational [Page 88]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The function prototype is
+
+ int sctp_bindx(int sd,
+ struct sockaddr *addrs,
+ int addrcnt,
+ int flags);
+
+ If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+ If the sd is an IPv6 socket, the addresses passed can either be IPv4
+ or IPv6 addresses.
+
+ A single address may be specified as INADDR_ANY for an IPv4 address,
+ or as IN6ADDR_ANY_INIT or in6addr_any for an IPv6 address; see
+ Section 3.1.2 for this usage.
+
+ addrs is a pointer to an array of one or more socket addresses. Each
+ address is contained in its appropriate structure. For an IPv6
+ socket, an array of sockaddr_in6 is used. For an IPv4 socket, an
+ array of sockaddr_in is used. The caller specifies the number of
+ addresses in the array with addrcnt. Note that the wildcard
+ addresses cannot be used in combination with non-wildcard addresses
+ on a socket with this function; doing so will result in an error.
+
+ On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns
+ -1 and sets errno to the appropriate error code.
+
+ For SCTP, the port given in each socket address must be the same, or
+ sctp_bindx() will fail, setting errno to EINVAL.
+
+ The flags parameter is formed from the bitwise OR of zero or more of
+ the following currently defined flags:
+
+ o SCTP_BINDX_ADD_ADDR
+
+ o SCTP_BINDX_REM_ADDR
+
+ SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the
+ socket (i.e., endpoint), and SCTP_BINDX_REM_ADDR directs SCTP to
+ remove the given addresses from the socket. The two flags are
+ mutually exclusive; if both are given, sctp_bindx() will fail with
+ EINVAL. A caller may not remove all addresses from a socket;
+ sctp_bindx() will reject such an attempt with EINVAL.
+
+ An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
+ additional addresses with an endpoint after calling bind(). Or, an
+ application can use sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some
+ addresses with which a listening socket is associated, so that no new
+ association accepted will be associated with these addresses. If the
+
+
+
+Stewart, et al. Informational [Page 89]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ endpoint supports dynamic address reconfiguration, an
+ SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause an endpoint to
+ send the appropriate message to its peers to change the peers'
+ address lists.
+
+ Adding and removing addresses from established associations is an
+ optional functionality. Implementations that do not support this
+ functionality should return -1 and set errno to EOPNOTSUPP.
+
+ sctp_bindx() can be called on an already bound socket or on an
+ unbound socket. If the socket is unbound and the first port number
+ in the addrs parameter is zero, the kernel will choose a port number.
+ All port numbers after the first one being 0 must also be zero. If
+ the first port number is not zero, the following port numbers must be
+ zero or have the same value as the first one. For an already bound
+ socket, all port numbers provided must be the bound one or 0.
+
+ sctp_bindx() is an atomic operation. Therefore, the binding will
+ either succeed on all addresses or fail on all addresses. If
+ multiple addresses are provided and the sctp_bindx() call fails,
+ there is no indication of which address is responsible for the
+ failure. The only way to identify the specific error indication is
+ to call sctp_bindx() sequentially with only one address per call.
+
+9.2. sctp_peeloff()
+
+ After an association is established on a one-to-many style socket,
+ the application may wish to branch off the association into a
+ separate socket/file descriptor.
+
+ This is particularly desirable when, for instance, the application
+ wishes to have a number of sporadic message senders/receivers remain
+ under the original one-to-many style socket but branch off these
+ associations carrying high-volume data traffic into their own
+ separate socket descriptors.
+
+ The application uses the sctp_peeloff() call to branch off an
+ association into a separate socket. (Note that the semantics are
+ somewhat changed from the traditional one-to-one style accept()
+ call.) Note also that the new socket is a one-to-one style socket.
+ Thus, it will be confined to operations allowed for a one-to-one
+ style socket.
+
+ The function prototype is
+
+ int sctp_peeloff(int sd,
+ sctp_assoc_t assoc_id);
+
+
+
+
+Stewart, et al. Informational [Page 90]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ and the arguments are
+
+ sd: The original one-to-many style socket descriptor returned from
+ the socket() system call (see Section 3.1.1).
+
+ assoc_id: The specified identifier of the association that is to be
+ branched off to a separate file descriptor. (Note that in a
+ traditional one-to-one style accept() call, this would be an out
+ parameter, but for the one-to-many style call, this is an in
+ parameter.)
+
+ The function returns a non-negative file descriptor representing the
+ branched-off association, or -1 if an error occurred. The variable
+ errno is then set appropriately.
+
+9.3. sctp_getpaddrs()
+
+ sctp_getpaddrs() returns all peer addresses in an association.
+
+ The function prototype is
+
+ int sctp_getpaddrs(int sd,
+ sctp_assoc_t id,
+ struct sockaddr **addrs);
+
+ On return, addrs will point to a dynamically allocated array of
+ sockaddr structures of the appropriate type for the socket type. The
+ caller should use sctp_freepaddrs() to free the memory. Note that
+ the in/out parameter addrs must not be NULL.
+
+ If sd is an IPv4 socket, the addresses returned will be all IPv4
+ addresses. If sd is an IPv6 socket, the addresses returned can be a
+ mix of IPv4 or IPv6 addresses, with IPv4 addresses returned according
+ to the SCTP_I_WANT_MAPPED_V4_ADDR option setting.
+
+ For one-to-many style sockets, id specifies the association to query.
+ For one-to-one style sockets, id is ignored.
+
+ On success, sctp_getpaddrs() returns the number of peer addresses in
+ the association. If there is no association on this socket,
+ sctp_getpaddrs() returns 0, and the value of *addrs is undefined. If
+ an error occurs, sctp_getpaddrs() returns -1, and the value of *addrs
+ is undefined.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 91]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+9.4. sctp_freepaddrs()
+
+ sctp_freepaddrs() frees all resources allocated by sctp_getpaddrs().
+
+ The function prototype is
+
+ void sctp_freepaddrs(struct sockaddr *addrs);
+
+ and addrs is the array of peer addresses returned by
+ sctp_getpaddrs().
+
+9.5. sctp_getladdrs()
+
+ sctp_getladdrs() returns all locally bound addresses on a socket.
+
+ The function prototype is
+
+ int sctp_getladdrs(int sd,
+ sctp_assoc_t id,
+ struct sockaddr **addrs);
+
+ On return, addrs will point to a dynamically allocated array of
+ sockaddr structures of the appropriate type for the socket type. The
+ caller should use sctp_freeladdrs() to free the memory. Note that
+ the in/out parameter addrs must not be NULL.
+
+ If sd is an IPv4 socket, the addresses returned will be all IPv4
+ addresses. If sd is an IPv6 socket, the addresses returned can be a
+ mix of IPv4 or IPv6 addresses, with IPv4 addresses returned according
+ to the SCTP_I_WANT_MAPPED_V4_ADDR option setting.
+
+ For one-to-many style sockets, id specifies the association to query.
+ For one-to-one style sockets, id is ignored.
+
+ If the id field is set to the value '0', then the locally bound
+ addresses are returned without regard to any particular association.
+
+ On success, sctp_getladdrs() returns the number of local addresses
+ bound to the socket. If the socket is unbound, sctp_getladdrs()
+ returns 0, and the value of *addrs is undefined. If an error occurs,
+ sctp_getladdrs() returns -1, and the value of *addrs is undefined.
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 92]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+9.6. sctp_freeladdrs()
+
+ sctp_freeladdrs() frees all resources allocated by sctp_getladdrs().
+
+ The function prototype is
+
+ void sctp_freeladdrs(struct sockaddr *addrs);
+
+ and addrs is the array of local addresses returned by
+ sctp_getladdrs().
+
+9.7. sctp_sendmsg() - DEPRECATED
+
+ This function is deprecated; sctp_sendv() (see Section 9.12) should
+ be used instead.
+
+ An implementation may provide a library function (or possibly system
+ call) to assist the user with the advanced features of SCTP.
+
+ The function prototype is
+
+ ssize_t sctp_sendmsg(int sd,
+ const void *msg,
+ size_t len,
+ const struct sockaddr *to,
+ socklen_t tolen,
+ uint32_t ppid,
+ uint32_t flags,
+ uint16_t stream_no,
+ uint32_t timetolive,
+ uint32_t context);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ msg: The message to be sent.
+
+ len: The length of the message.
+
+ to: The destination address of the message.
+
+ tolen: The length of the destination address.
+
+ ppid: The same as sinfo_ppid (see Section 5.3.2).
+
+ flags: The same as sinfo_flags (see Section 5.3.2).
+
+
+
+
+Stewart, et al. Informational [Page 93]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ stream_no: The same as sinfo_stream (see Section 5.3.2).
+
+ timetolive: The same as sinfo_timetolive (see Section 5.3.2).
+
+ context: The same as sinfo_context (see Section 5.3.2).
+
+ The call returns the number of characters sent, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+ Sending a message using sctp_sendmsg() is atomic (unless explicit EOR
+ marking is enabled on the socket specified by sd).
+
+ Using sctp_sendmsg() on a non-connected one-to-one style socket for
+ implicit connection setup may or may not work, depending on the SCTP
+ implementation.
+
+9.8. sctp_recvmsg() - DEPRECATED
+
+ This function is deprecated; sctp_recvv() (see Section 9.13) should
+ be used instead.
+
+ An implementation may provide a library function (or possibly system
+ call) to assist the user with the advanced features of SCTP. Note
+ that in order for the sctp_sndrcvinfo structure to be filled in by
+ sctp_recvmsg(), the caller must enable the sctp_data_io_event with
+ the SCTP_EVENTS option. Note that the setting of the
+ SCTP_USE_EXT_RCVINFO will affect this function as well, causing the
+ sctp_sndrcvinfo information to be extended.
+
+ The function prototype is
+
+ ssize_t sctp_recvmsg(int sd,
+ void *msg,
+ size_t len,
+ struct sockaddr *from,
+ socklen_t *fromlen
+ struct sctp_sndrcvinfo *sinfo
+ int *msg_flags);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ msg: The message buffer to be filled.
+
+ len: The length of the message buffer.
+
+
+
+
+
+Stewart, et al. Informational [Page 94]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ from: A pointer to an address to be filled with the address of the
+ sender of this message.
+
+ fromlen: An in/out parameter describing the from length.
+
+ sinfo: A pointer to an sctp_sndrcvinfo structure to be filled upon
+ receipt of the message.
+
+ msg_flags: A pointer to an integer to be filled with any message
+ flags (e.g., MSG_NOTIFICATION). Note that this field is an in-out
+ field. Options for the receive may also be passed into the value
+ (e.g., MSG_PEEK). On return from the call, the msg_flags value
+ will be different than what was sent in to the call. If
+ implemented via a recvmsg() call, the msg_flags parameter should
+ only contain the value of the flags from the recvmsg() call.
+
+ The call returns the number of bytes received, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+9.9. sctp_connectx()
+
+ An implementation may provide a library function (or possibly system
+ call) to assist the user with associating to an endpoint that is
+ multi-homed. Much like sctp_bindx(), this call allows a caller to
+ specify multiple addresses at which a peer can be reached. The way
+ the SCTP stack uses the list of addresses to set up the association
+ is implementation dependent. This function only specifies that the
+ stack will try to make use of all of the addresses in the list when
+ needed.
+
+ Note that the list of addresses passed in is only used for setting up
+ the association. It does not necessarily equal the set of addresses
+ the peer uses for the resulting association. If the caller wants to
+ find out the set of peer addresses, it must use sctp_getpaddrs() to
+ retrieve them after the association has been set up.
+
+ The function prototype is
+
+ int sctp_connectx(int sd,
+ struct sockaddr *addrs,
+ int addrcnt,
+ sctp_assoc_t *id);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ addrs: An array of addresses.
+
+
+
+Stewart, et al. Informational [Page 95]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ addrcnt: The number of addresses in the array.
+
+ id: An output parameter that, if passed in as non-NULL, will return
+ the association identifier for the newly created association (if
+ successful).
+
+ The call returns 0 on success or -1 if an error occurred. The
+ variable errno is then set appropriately.
+
+9.10. sctp_send() - DEPRECATED
+
+ This function is deprecated; sctp_sendv() should be used instead.
+
+ An implementation may provide another alternative function or system
+ call to assist an application with the sending of data without the
+ use of the cmsghdr structures.
+
+ The function prototype is
+
+ ssize_t sctp_send(int sd,
+ const void *msg,
+ size_t len,
+ const struct sctp_sndrcvinfo *sinfo,
+ int flags);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ msg: The message to be sent.
+
+ len: The length of the message.
+
+ sinfo: A pointer to an sctp_sndrcvinfo structure used as described
+ in Section 5.3.2 for a sendmsg() call.
+
+ flags: The same flags as used by the sendmsg() call flags (e.g.,
+ MSG_DONTROUTE).
+
+ The call returns the number of bytes sent, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+ This function call may also be used to terminate an association using
+ an association identifier by setting the sinfo.sinfo_flags to
+ SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs
+ to be terminated. In such a case, len can be zero.
+
+
+
+
+
+Stewart, et al. Informational [Page 96]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Using sctp_send() on a non-connected one-to-one style socket for
+ implicit connection setup may or may not work, depending on the SCTP
+ implementation.
+
+ Sending a message using sctp_send() is atomic unless explicit EOR
+ marking is enabled on the socket specified by sd.
+
+9.11. sctp_sendx() - DEPRECATED
+
+ This function is deprecated; sctp_sendv() should be used instead.
+
+ An implementation may provide another alternative function or system
+ call to assist an application with the sending of data without the
+ use of the cmsghdr structure, and to provide a list of addresses.
+ The list of addresses is provided for implicit association setup. In
+ such a case, the list of addresses serves the same purpose as the
+ addresses given in sctp_connectx() (see Section 9.9).
+
+ The function prototype is
+
+ ssize_t sctp_sendx(int sd,
+ const void *msg,
+ size_t len,
+ struct sockaddr *addrs,
+ int addrcnt,
+ struct sctp_sndrcvinfo *sinfo,
+ int flags);
+
+ and the arguments are
+
+ sd: The socket descriptor.
+
+ msg: The message to be sent.
+
+ len: The length of the message.
+
+ addrs: An array of addresses.
+
+ addrcnt: The number of addresses in the array.
+
+ sinfo: A pointer to an sctp_sndrcvinfo structure used as described
+ in Section 5.3.2 for a sendmsg() call.
+
+ flags: The same flags as used by the sendmsg() call flags (e.g.,
+ MSG_DONTROUTE).
+
+ The call returns the number of bytes sent, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+
+
+Stewart, et al. Informational [Page 97]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ Note that in the case of implicit connection setup, on return from
+ this call, the sinfo_assoc_id field of the sinfo structure will
+ contain the new association identifier.
+
+ This function call may also be used to terminate an association using
+ an association identifier by setting the sinfo.sinfo_flags to
+ SCTP_EOF and the sinfo.sinfo_assoc_id to the association that needs
+ to be terminated. In such a case, len would be zero.
+
+ Sending a message using sctp_sendx() is atomic unless explicit EOR
+ marking is enabled on the socket specified by sd.
+
+ Using sctp_sendx() on a non-connected one-to-one style socket for
+ implicit connection setup may or may not work, depending on the SCTP
+ implementation.
+
+9.12. sctp_sendv()
+
+ The function prototype is
+
+ ssize_t sctp_sendv(int sd,
+ const struct iovec *iov,
+ int iovcnt,
+ struct sockaddr *addrs,
+ int addrcnt,
+ void *info,
+ socklen_t infolen,
+ unsigned int infotype,
+ int flags);
+
+ The function sctp_sendv() provides an extensible way for an
+ application to communicate different send attributes to the SCTP
+ stack when sending a message. An implementation may provide
+ sctp_sendv() as a library function or a system call.
+
+ This document defines three types of attributes that can be used to
+ describe a message to be sent. They are struct sctp_sndinfo
+ (Section 5.3.4), struct sctp_prinfo (Section 5.3.7), and struct
+ sctp_authinfo (Section 5.3.8). The following structure,
+ sctp_sendv_spa, is defined to be used when more than one of the above
+ attributes are needed to describe a message to be sent.
+
+ struct sctp_sendv_spa {
+ uint32_t sendv_flags;
+ struct sctp_sndinfo sendv_sndinfo;
+ struct sctp_prinfo sendv_prinfo;
+ struct sctp_authinfo sendv_authinfo;
+ };
+
+
+
+Stewart, et al. Informational [Page 98]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ The sendv_flags field holds a bitwise OR of SCTP_SEND_SNDINFO_VALID,
+ SCTP_SEND_PRINFO_VALID, and SCTP_SEND_AUTHINFO_VALID indicating if
+ the sendv_sndinfo/sendv_prinfo/sendv_authinfo fields contain valid
+ information.
+
+ In future, when new send attributes are needed, new structures can be
+ defined. But those new structures do not need to be based on any of
+ the above defined structures.
+
+ The function takes the following arguments:
+
+ sd: The socket descriptor.
+
+ iov: The gather buffer. The data in the buffer is treated as a
+ single user message.
+
+ iovcnt: The number of elements in iov.
+
+ addrs: An array of addresses to be used to set up an association or
+ a single address to be used to send the message. NULL is passed
+ in if the caller neither wants to set up an association nor wants
+ to send the message to a specific address.
+
+ addrcnt: The number of addresses in the addrs array.
+
+ info: A pointer to the buffer containing the attribute associated
+ with the message to be sent. The type is indicated by the
+ info_type parameter.
+
+ infolen: The length of info, in bytes.
+
+ infotype: Identifies the type of the information provided in info.
+ The current defined values are as follows:
+
+ SCTP_SENDV_NOINFO: No information is provided. The parameter
+ info is a NULL pointer, and infolen is 0.
+
+ SCTP_SENDV_SNDINFO: The parameter info is pointing to a struct
+ sctp_sndinfo.
+
+ SCTP_SENDV_PRINFO: The parameter info is pointing to a struct
+ sctp_prinfo.
+
+ SCTP_SENDV_AUTHINFO: The parameter info is pointing to a struct
+ sctp_authinfo.
+
+ SCTP_SENDV_SPA: The parameter info is pointing to a struct
+ sctp_sendv_spa.
+
+
+
+Stewart, et al. Informational [Page 99]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ flags: The same flags as used by the sendmsg() call flags (e.g.,
+ MSG_DONTROUTE).
+
+ The call returns the number of bytes sent, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+ A note on the one-to-many style socket: The struct sctp_sndinfo
+ attribute must always be used in order to specify the association on
+ which the message is to be sent. The only case where it is not
+ needed is when this call is used to set up a new association.
+
+ The caller provides a list of addresses in the addrs parameter to set
+ up an association. This function will behave like calling
+ sctp_connectx() (see Section 9.9), first using the list of addresses
+ and then calling sendmsg() with the given message and attributes.
+ For a one-to-many style socket, if the struct sctp_sndinfo attribute
+ is provided, the snd_assoc_id field must be 0. When this function
+ returns, the snd_assoc_id field will contain the association
+ identifier of the newly established association. Note that the
+ struct sctp_sndinfo attribute is not required to set up an
+ association for a one-to-many style socket. If this attribute is not
+ provided, the caller can enable the SCTP_ASSOC_CHANGE notification
+ and use the SCTP_COMM_UP message to find out the association
+ identifier.
+
+ If the caller wants to send the message to a specific peer address
+ (hence overriding the primary address), it can provide the specific
+ address in the addrs parameter and provide a struct sctp_sndinfo
+ attribute with the field snd_flags set to SCTP_ADDR_OVER.
+
+ This function call may also be used to terminate an association. The
+ caller provides an sctp_sndinfo attribute with the snd_flags set to
+ SCTP_EOF. In this case, len would be zero.
+
+ Sending a message using sctp_sendv() is atomic unless explicit EOR
+ marking is enabled on the socket specified by sd.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 100]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+9.13. sctp_recvv()
+
+ The function prototype is
+
+ ssize_t sctp_recvv(int sd,
+ const struct iovec *iov,
+ int iovlen,
+ struct sockaddr *from,
+ socklen_t *fromlen,
+ void *info,
+ socklen_t *infolen,
+ unsigned int *infotype,
+ int *flags);
+
+ The function sctp_recvv() provides an extensible way for the SCTP
+ stack to pass up different SCTP attributes associated with a received
+ message to an application. An implementation may provide
+ sctp_recvv() as a library function or as a system call.
+
+ This document defines two types of attributes that can be returned by
+ this call: the attribute of the received message and the attribute of
+ the next message in the receive buffer. The caller enables the
+ SCTP_RECVRCVINFO and SCTP_RECVNXTINFO socket options, respectively,
+ to receive these attributes. Attributes of the received message are
+ returned in struct sctp_rcvinfo (Section 5.3.5), and attributes of
+ the next message are returned in struct sctp_nxtinfo (Section 5.3.6).
+ If both options are enabled, both attributes are returned using the
+ following structure.
+
+ struct sctp_recvv_rn {
+ struct sctp_rcvinfo recvv_rcvinfo;
+ struct sctp_nxtinfo recvv_nxtinfo;
+ };
+
+ In future, new structures can be defined to hold new types of
+ attributes. The new structures do not need to be based on struct
+ sctp_recvv_rn or struct sctp_rcvinfo.
+
+ This function takes the following arguments:
+
+ sd: The socket descriptor.
+
+ iov: The scatter buffer. Only one user message is returned in this
+ buffer.
+
+ iovlen: The number of elements in iov.
+
+
+
+
+
+Stewart, et al. Informational [Page 101]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ from: A pointer to an address to be filled with the sender of the
+ received message's address.
+
+ fromlen: An in/out parameter describing the from length.
+
+ info: A pointer to the buffer to hold the attributes of the received
+ message. The structure type of info is determined by the
+ info_type parameter.
+
+ infolen: An in/out parameter describing the size of the info buffer.
+
+ infotype: On return, *info_type is set to the type of the info
+ buffer. The current defined values are as follows:
+
+ SCTP_RECVV_NOINFO: If both SCTP_RECVRCVINFO and SCTP_RECVNXTINFO
+ options are not enabled, no attribute will be returned. If
+ only the SCTP_RECVNXTINFO option is enabled but there is no
+ next message in the buffer, no attribute will be returned. In
+ these cases, *info_type will be set to SCTP_RECVV_NOINFO.
+
+ SCTP_RECVV_RCVINFO: The type of info is struct sctp_rcvinfo, and
+ the attribute relates to the received message.
+
+ SCTP_RECVV_NXTINFO: The type of info is struct sctp_nxtinfo, and
+ the attribute relates to the next message in the receive
+ buffer. This is the case when only the SCTP_RECVNXTINFO option
+ is enabled and there is a next message in the buffer.
+
+ SCTP_RECVV_RN: The type of info is struct sctp_recvv_rn. The
+ recvv_rcvinfo field is the attribute of the received message,
+ and the recvv_nxtinfo field is the attribute of the next
+ message in the buffer. This is the case when both
+ SCTP_RECVRCVINFO and SCTP_RECVNXTINFO options are enabled and
+ there is a next message in the receive buffer.
+
+ flags: A pointer to an integer to be filled with any message flags
+ (e.g., MSG_NOTIFICATION). Note that this field is an in/out
+ parameter. Options for the receive may also be passed into the
+ value (e.g., MSG_PEEK). On return from the call, the flags value
+ will be different than what was sent in to the call. If
+ implemented via a recvmsg() call, the flags should only contain
+ the value of the flags from the recvmsg() call when calling
+ sctp_recvv(), and on return it has the value from msg_flags.
+
+ The call returns the number of bytes received, or -1 if an error
+ occurred. The variable errno is then set appropriately.
+
+
+
+
+
+Stewart, et al. Informational [Page 102]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+10. Security Considerations
+
+ Many TCP and UDP implementations reserve port numbers below 1024 for
+ privileged users. If the target platform supports privileged users,
+ the SCTP implementation should restrict the ability to call bind() or
+ sctp_bindx() on these port numbers to privileged users.
+
+ Similarly, unprivileged users should not be able to set protocol
+ parameters that could result in the congestion control algorithm
+ being more aggressive than permitted on the public Internet. These
+ parameters are as follows:
+
+ o struct sctp_rtoinfo
+
+ If an unprivileged user inherits a one-to-many style socket with open
+ associations on a privileged port, accepting new associations might
+ be permitted, but opening new associations should not be permitted.
+ This could be relevant for the r* family (rsh, rlogin, rwho, ...) of
+ protocols.
+
+ Applications using the one-to-many style sockets and using the
+ interleave level (if 0) are subject to denial-of-service attacks, as
+ described in Section 8.1.20.
+
+ Applications needing transport layer security can use Datagram
+ Transport Layer Security/SCTP (DTLS/SCTP) as specified in [RFC6083].
+ This can be implemented using the sockets API described in this
+ document.
+
+11. Acknowledgments
+
+ Special acknowledgment is given to Ken Fujita, Jonathan Woods,
+ Qiaobing Xie, and La Monte Yarroll, who helped extensively in the
+ early formation of this document.
+
+ The authors also wish to thank Kavitha Baratakke, Mike Bartlett,
+ Martin Becke, Jon Berger, Mark Butler, Thomas Dreibholz, Andreas
+ Fink, Scott Kimble, Jonathan Leighton, Renee Revis, Irene Ruengeler,
+ Dan Wing, and many others on the TSVWG mailing list for contributing
+ valuable comments.
+
+ A special thanks to Phillip Conrad, for his suggested text, quick and
+ constructive insights, and most of all his persistent fighting to
+ keep the interface to SCTP usable for the application programmer.
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 103]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+12. References
+
+12.1. Normative References
+
+ [IEEE-1003.1-2008]
+ Institute of Electrical and Electronics Engineers,
+ "Information Technology - Portable Operating System
+ Interface (POSIX)", IEEE Standard 1003.1, 2008.
+
+ [RFC3493] Gilligan, R., Thomson, S., Bound, J., McCann, J., and W.
+ Stevens, "Basic Socket Interface Extensions for IPv6",
+ RFC 3493, February 2003.
+
+ [RFC3542] Stevens, W., Thomas, M., Nordmark, E., and T. Jinmei,
+ "Advanced Sockets Application Program Interface (API) for
+ IPv6", RFC 3542, May 2003.
+
+ [RFC3758] Stewart, R., Ramalho, M., Xie, Q., Tuexen, M., and P.
+ Conrad, "Stream Control Transmission Protocol (SCTP)
+ Partial Reliability Extension", RFC 3758, May 2004.
+
+ [RFC4895] Tuexen, M., Stewart, R., Lei, P., and E. Rescorla,
+ "Authenticated Chunks for the Stream Control Transmission
+ Protocol (SCTP)", RFC 4895, August 2007.
+
+ [RFC4960] Stewart, R., Ed., "Stream Control Transmission Protocol",
+ RFC 4960, September 2007.
+
+ [RFC5061] Stewart, R., Xie, Q., Tuexen, M., Maruyama, S., and M.
+ Kozuka, "Stream Control Transmission Protocol (SCTP)
+ Dynamic Address Reconfiguration", RFC 5061,
+ September 2007.
+
+12.2. Informative References
+
+ [RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
+ August 1980.
+
+ [RFC0793] Postel, J., "Transmission Control Protocol", STD 7,
+ RFC 793, September 1981.
+
+ [RFC1644] Braden, R., "T/TCP -- TCP Extensions for Transactions
+ Functional Specification", RFC 1644, July 1994.
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 104]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ [RFC6083] Tuexen, M., Seggelmann, R., and E. Rescorla, "Datagram
+ Transport Layer Security (DTLS) for Stream Control
+ Transmission Protocol (SCTP)", RFC 6083, January 2011.
+
+ [RFC6247] Eggert, L., "Moving the Undeployed TCP Extensions RFC
+ 1072, RFC 1106, RFC 1110, RFC 1145, RFC 1146, RFC 1379,
+ RFC 1644, and RFC 1693 to Historic Status", RFC 6247,
+ May 2011.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 105]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+Appendix A. Example Using One-to-One Style Sockets
+
+ The following code is an implementation of a simple client that sends
+ a number of messages marked for unordered delivery to an echo server
+ making use of all outgoing streams. The example shows how to use
+ some features of one-to-one style IPv4 SCTP sockets, including
+
+ o Creating and connecting an SCTP socket.
+
+ o Making a request to negotiate a number of outgoing streams.
+
+ o Determining the negotiated number of outgoing streams.
+
+ o Setting an adaptation layer indication.
+
+ o Sending messages with a given payload protocol identifier on a
+ particular stream using sctp_sendv().
+
+ <CODE BEGINS>
+ /*
+
+ Copyright (c) 2011 IETF Trust and the persons identified
+ as authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with
+ or without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents (http://trustee.ietf.org/license-info).
+
+ */
+
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netinet/sctp.h>
+ #include <arpa/inet.h>
+ #include <string.h>
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+
+ #define PORT 9
+ #define ADDR "127.0.0.1"
+ #define SIZE_OF_MESSAGE 1000
+ #define NUMBER_OF_MESSAGES 10
+ #define PPID 1234
+
+
+
+
+Stewart, et al. Informational [Page 106]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ int
+ main(void) {
+ unsigned int i;
+ int sd;
+ struct sockaddr_in addr;
+ char buffer[SIZE_OF_MESSAGE];
+ struct iovec iov;
+ struct sctp_status status;
+ struct sctp_initmsg init;
+ struct sctp_sndinfo info;
+ struct sctp_setadaptation ind;
+ socklen_t opt_len;
+
+ /* Create a one-to-one style SCTP socket. */
+ if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ /* Prepare for requesting 2048 outgoing streams. */
+ memset(&init, 0, sizeof(init));
+ init.sinit_num_ostreams = 2048;
+ if (setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG,
+ &init, (socklen_t)sizeof(init)) < 0) {
+ perror("setsockopt");
+ exit(1);
+ }
+
+ ind.ssb_adaptation_ind = 0x01020304;
+ if (setsockopt(sd, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER,
+ &ind, (socklen_t)sizeof(ind)) < 0) {
+ perror("setsockopt");
+ exit(1);
+ }
+
+ /* Connect to the discard server. */
+ memset(&addr, 0, sizeof(addr));
+ #ifdef HAVE_SIN_LEN
+ addr.sin_len = sizeof(struct sockaddr_in);
+ #endif
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PORT);
+ addr.sin_addr.s_addr = inet_addr(ADDR);
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 107]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ if (connect(sd,
+ (const struct sockaddr *)&addr,
+ sizeof(struct sockaddr_in)) < 0) {
+ perror("connect");
+ exit(1);
+ }
+
+ /* Get the actual number of outgoing streams. */
+ memset(&status, 0, sizeof(status));
+ opt_len = (socklen_t)sizeof(status);
+ if (getsockopt(sd, IPPROTO_SCTP, SCTP_STATUS,
+ &status, &opt_len) < 0) {
+ perror("getsockopt");
+ exit(1);
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.snd_ppid = htonl(PPID);
+ info.snd_flags = SCTP_UNORDERED;
+ memset(buffer, 'A', SIZE_OF_MESSAGE);
+ iov.iov_base = buffer;
+ iov.iov_len = SIZE_OF_MESSAGE;
+ for (i = 0; i < NUMBER_OF_MESSAGES; i++) {
+ info.snd_sid = i % status.sstat_outstrms;
+ if (sctp_sendv(sd,
+ (const struct iovec *)&iov, 1,
+ NULL, 0,
+ &info, sizeof(info), SCTP_SENDV_SNDINFO,
+ 0) < 0) {
+ perror("sctp_sendv");
+ exit(1);
+ }
+ }
+
+ if (close(sd) < 0) {
+ perror("close");
+ exit(1);
+ }
+ return(0);
+ }
+ <CODE ENDS>
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 108]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+Appendix B. Example Using One-to-Many Style Sockets
+
+ The following code is a simple implementation of a discard server
+ over SCTP. The example shows how to use some features of one-to-many
+ style IPv6 SCTP sockets, including
+
+ o Opening and binding of a socket.
+
+ o Enabling notifications.
+
+ o Handling notifications.
+
+ o Configuring the auto-close timer.
+
+ o Using sctp_recvv() to receive messages.
+
+ Please note that this server can be used in combination with the
+ client described in Appendix A.
+
+ <CODE BEGINS>
+ /*
+
+ Copyright (c) 2011 IETF Trust and the persons identified
+ as authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with
+ or without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents (http://trustee.ietf.org/license-info).
+
+ */
+
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netinet/sctp.h>
+ #include <arpa/inet.h>
+ #include <string.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ #define BUFFER_SIZE (1<<16)
+ #define PORT 9
+ #define ADDR "0.0.0.0"
+ #define TIMEOUT 5
+
+
+
+
+Stewart, et al. Informational [Page 109]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ static void
+ print_notification(void *buf)
+ {
+ struct sctp_assoc_change *sac;
+ struct sctp_paddr_change *spc;
+ struct sctp_adaptation_event *sad;
+ union sctp_notification *snp;
+ char addrbuf[INET6_ADDRSTRLEN];
+ const char *ap;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ snp = buf;
+
+ switch (snp->sn_header.sn_type) {
+ case SCTP_ASSOC_CHANGE:
+ sac = &snp->sn_assoc_change;
+ printf("^^^ Association change: ");
+ switch (sac->sac_state) {
+ case SCTP_COMM_UP:
+ printf("Communication up (streams (in/out)=(%u/%u)).\n",
+ sac->sac_inbound_streams, sac->sac_outbound_streams);
+ break;
+ case SCTP_COMM_LOST:
+ printf("Communication lost (error=%d).\n", sac->sac_error);
+ break;
+ case SCTP_RESTART:
+ printf("Communication restarted (streams (in/out)=(%u/%u).\n",
+ sac->sac_inbound_streams, sac->sac_outbound_streams);
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ printf("Communication completed.\n");
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ printf("Communication couldn't be started.\n");
+ break;
+ default:
+ printf("Unknown state: %d.\n", sac->sac_state);
+ break;
+ }
+ break;
+ case SCTP_PEER_ADDR_CHANGE:
+ spc = &snp->sn_paddr_change;
+ if (spc->spc_aaddr.ss_family == AF_INET) {
+ sin = (struct sockaddr_in *)&spc->spc_aaddr;
+ ap = inet_ntop(AF_INET, &sin->sin_addr,
+ addrbuf, INET6_ADDRSTRLEN);
+ } else {
+
+
+
+Stewart, et al. Informational [Page 110]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+ ap = inet_ntop(AF_INET6, &sin6->sin6_addr,
+ addrbuf, INET6_ADDRSTRLEN);
+ }
+ printf("^^^ Peer Address change: %s ", ap);
+ switch (spc->spc_state) {
+ case SCTP_ADDR_AVAILABLE:
+ printf("is available.\n");
+ break;
+ case SCTP_ADDR_UNREACHABLE:
+ printf("is not available (error=%d).\n", spc->spc_error);
+ break;
+ case SCTP_ADDR_REMOVED:
+ printf("was removed.\n");
+ break;
+ case SCTP_ADDR_ADDED:
+ printf("was added.\n");
+ break;
+ case SCTP_ADDR_MADE_PRIM:
+ printf("is primary.\n");
+ break;
+ default:
+ printf("unknown state (%d).\n", spc->spc_state);
+ break;
+ }
+ break;
+ case SCTP_SHUTDOWN_EVENT:
+ printf("^^^ Shutdown received.\n");
+ break;
+ case SCTP_ADAPTATION_INDICATION:
+ sad = &snp->sn_adaptation_event;
+ printf("^^^ Adaptation indication 0x%08x received.\n",
+ sad->sai_adaptation_ind);
+ break;
+ default:
+ printf("^^^ Unknown event of type: %u.\n",
+ snp->sn_header.sn_type);
+ break;
+ };
+ }
+
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 111]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ int
+ main(void) {
+ int sd, flags, timeout, on;
+ ssize_t n;
+ unsigned int i;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } addr;
+ socklen_t fromlen, infolen;
+ struct sctp_rcvinfo info;
+ unsigned int infotype;
+ struct iovec iov;
+ char buffer[BUFFER_SIZE];
+ struct sctp_event event;
+ uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
+ SCTP_PEER_ADDR_CHANGE,
+ SCTP_SHUTDOWN_EVENT,
+ SCTP_ADAPTATION_INDICATION};
+
+ /* Create a one-to-many style SCTP socket. */
+ if ((sd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ /* Enable the events of interest. */
+ memset(&event, 0, sizeof(event));
+ event.se_assoc_id = SCTP_FUTURE_ASSOC;
+ event.se_on = 1;
+ for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
+ event.se_type = event_types[i];
+ if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENT,
+ &event, sizeof(event)) < 0) {
+ perror("setsockopt");
+ exit(1);
+ }
+ }
+
+ /* Configure auto-close timer. */
+ timeout = TIMEOUT;
+ if (setsockopt(sd, IPPROTO_SCTP, SCTP_AUTOCLOSE,
+ &timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt SCTP_AUTOCLOSE");
+ exit(1);
+ }
+
+
+
+
+Stewart, et al. Informational [Page 112]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ /* Enable delivery of SCTP_RCVINFO. */
+ on = 1;
+ if (setsockopt(sd, IPPROTO_SCTP, SCTP_RECVRCVINFO,
+ &on, sizeof(on)) < 0) {
+ perror("setsockopt SCTP_RECVRCVINFO");
+ exit(1);
+ }
+
+ /* Bind the socket to all local addresses. */
+ memset(&addr, 0, sizeof(addr));
+ #ifdef HAVE_SIN6_LEN
+ addr.sin6.sin6_len = sizeof(addr.sin6);
+ #endif
+ addr.sin6.sin6_family = AF_INET6;
+ addr.sin6.sin6_port = htons(PORT);
+ addr.sin6.sin6_addr = in6addr_any;
+ if (bind(sd, &addr.sa, sizeof(addr.sin6)) < 0) {
+ perror("bind");
+ exit(1);
+ }
+ /* Enable accepting associations. */
+ if (listen(sd, 1) < 0) {
+ perror("listen");
+ exit(1);
+ }
+
+ for (;;) {
+ flags = 0;
+ memset(&addr, 0, sizeof(addr));
+ fromlen = (socklen_t)sizeof(addr);
+ memset(&info, 0, sizeof(info));
+ infolen = (socklen_t)sizeof(info);
+ infotype = 0;
+ iov.iov_base = buffer;
+ iov.iov_len = BUFFER_SIZE;
+
+ n = sctp_recvv(sd, &iov, 1,
+ &addr.sa, &fromlen,
+ &info, &infolen, &infotype,
+ &flags);
+
+ if (flags & MSG_NOTIFICATION) {
+ print_notification(iov.iov_base);
+ } else {
+ char addrbuf[INET6_ADDRSTRLEN];
+ const char *ap;
+ in_port_t port;
+
+
+
+
+Stewart, et al. Informational [Page 113]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+ if (addr.sa.sa_family == AF_INET) {
+ ap = inet_ntop(AF_INET, &addr.sin.sin_addr,
+ addrbuf, INET6_ADDRSTRLEN);
+ port = ntohs(addr.sin.sin_port);
+ } else {
+ ap = inet_ntop(AF_INET6, &addr.sin6.sin6_addr,
+ addrbuf, INET6_ADDRSTRLEN);
+ port = ntohs(addr.sin6.sin6_port);
+ }
+ printf("Message received from %s:%u: len=%d",
+ ap, port, (int)n);
+ switch (infotype) {
+ case SCTP_RECVV_RCVINFO:
+ printf(", sid=%u", info.rcv_sid);
+ if (info.rcv_flags & SCTP_UNORDERED) {
+ printf(", unordered");
+ } else {
+ printf(", ssn=%u", info.rcv_ssn);
+ }
+ printf(", tsn=%u", info.rcv_tsn);
+ printf(", ppid=%u.\n", ntohl(info.rcv_ppid));
+ break;
+ case SCTP_RECVV_NOINFO:
+ case SCTP_RECVV_NXTINFO:
+ case SCTP_RECVV_RN:
+ printf(".\n");
+ break;
+ default:
+ printf(" unknown infotype.\n");
+ }
+ }
+ }
+
+ if (close(sd) < 0) {
+ perror("close");
+ exit(1);
+ }
+
+ return (0);
+ }
+ <CODE ENDS>
+
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 114]
+
+RFC 6458 SCTP Sockets API December 2011
+
+
+Authors' Addresses
+
+ Randall R. Stewart
+ Adara Networks
+ Chapin, SC 29036
+ USA
+
+ EMail: randall@lakerest.net
+
+
+ Michael Tuexen
+ Muenster University of Applied Sciences
+ Stegerwaldstr. 39
+ 48565 Steinfurt
+ Germany
+
+ EMail: tuexen@fh-muenster.de
+
+
+ Kacheong Poon
+ Oracle Corporation
+
+ EMail: ka-cheong.poon@oracle.com
+
+
+ Peter Lei
+ Cisco Systems, Inc.
+ 9501 Technology Blvd.
+ West Office Center
+ Rosemont, IL 60018
+ USA
+
+ EMail: peterlei@cisco.com
+
+
+ Vladislav Yasevich
+ HP
+ 110 Spitrook Rd.
+ Nashua, NH 03062
+ USA
+
+ EMail: vladislav.yasevich@hp.com
+
+
+
+
+
+
+
+
+
+Stewart, et al. Informational [Page 115]
+
diff --git a/doc/states.txt b/doc/states.txt
new file mode 100644
index 0000000..de05f1f
--- /dev/null
+++ b/doc/states.txt
@@ -0,0 +1,105 @@
+#!enscript -G -r -f Courier7 -o states.ps -
+Version 0.11. Best viewed on a 176 column terminal or printed with the above command.
+
+This table shows actions in response to all possible messages in all
+possible states for SCTP. It is based on RFC2960.
+
+Arguments to the state functions:
+(asoc, {(skb, verificationTag, singleton) || (primitive_args) || nil} )
+- asoc is the association in question, NULL for CLOSED
+- The second arg is a coproduct depending on the event
+-- for a chunk we have:
+--- skb is the inbound chunk
+--- verificationTag is from the SCTP header
+--- singleton is true if the chunk is alone in its packet
+-- for a primitive we have
+--- primitive_args is a union which captures the args to all primitives
+-- for other events the second argument is undefined.
+
+Return values of the state functions:
+(asoc, NewState, timers, responsePacket, ULPNotice, error, unique)
+- asoc is the association in question, NB: might be a CLOSED asoc
+- NewState is the next state the machine should move to
+- timers is new timer values, NULL if not needed
+- responsePacket is an outbound packet to send, NULL if not needed
+- ULPNotice is any response or notification we need to send to the ULP
+- error is an error code, NULL if there was no error
+- unique is a boolean that tells us if the chunk has to be alone in its packet. undef if the event was not a chunk.
+
+Most of the state functions should be self-explainatory. Here are some which might not be clear:
+violation - Can not happen -- the other guy is violating the protocol.
+other_stupid - The other implementation is doing a legal thing which
+ is a BAD IDEA.
+lucky - We did something legal but stupid and got away with it :-).
+bug - We did something impossible.
+
+* in the left column means that this is "normal sender" flow.
++ in the left column means that this is "normal receiver" flow.
+% marks chunks which may NOT be bundled. See 3.0 and 6.10.
+! marks special security considerations
+Count the >'s to calculate state transitions.
+0 - Fixed in Version 11.
+1 - If we see more INIT ACK's than we sent INIT's, we may be under hijack attack
+2 - 3.3.10.10 is a special case of 5.2.4 for SHUTDOWN-ACK-SENT.
+3 - 6.0 says that OUTBOUND data should only be generated in ESTABLISHED, SHUTDOWN-PENDING, and SHUTDOWN-RECEIVED.
+4 - Contradiction fixed in v11.
+5 - implementation specific (safe to leave unspecified)
+6 -
+7 - This is not explicit but is a logical consequence of other requirements.
+8 - If his HEARTBEAT beats his cookie you'll send an ABORT.
+9 - There is a finite probability that this orderly shutdown will turn into an ABORT.
+
+
+ | CLOSED | COOKIE-WAIT | COOKIE-ECHOED | ESTABLISHED | SHUTDOWN-PENDING | SHUTDOWN-SENT | SHUTDOWN-RECEIVED | SHUTDOWN-ACK-SENT
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Chunks | | | | | | | |
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+ABORT | pdiscard(8.4.2)| do_9_1_abort <|do_9_1_abort <<| do_9_1_abort <<<| do_9_1_abort >>>>| do_9_1_abort >>>| do_9_1_abort >>| do_9_1_abort >
+INIT %|*do_5_1B_init | do_5_2_1_siminit| do_5_2_1_siminit| do_5_2_2_dupinit | do_5_2_2_dupinit | do_5_2_2_dupinit| do_5_2_2_dupinit | do_9_2_reshut
+INIT ACK %| discard(5.2.3)|*do_5_1C_ack >| discard(5.2.3) 1| discard(5.2.3) 1| discard(5.2.3) 1| discard(5.2.3) 1| discard(5.2.3) 1| discard(5.2.3) 1
+COOKIE ECHO |*do_5_1D_ce >>>| do_5_2_4_dupcook| do_5_2_4_dupcook| do_5_2_4_dupcook | do_5_2_4_dupcook | do_5_2_4_dupcook| do_5_2_4_dupcook | do_5_2_4_dupcook 2
+COOKIE ACK | discard 4| discard(5.2.5) |*do_5_1E_ca >| discard(5.2.5) | discard(5.2.5) | discard(5.2.5) | discard(5.2.5) | discard(5.2.5)
+SHUTDOWN | tabort_8_4_8 | discard(9.2) 0| discard(9.2) 0|+do_9_2_shut >>>| discard(0.2) 0| do_9_2_shutack>>| discard(0.2) 0| discard(0.2) 0
+SHUTDOWN ACK | do_8_4_5_shut | do_8_4_5_shut | discard 0| violation 7| violation 7|*do_9_2_final >>>| violation 7| do_9_2_final >
+SHUTDOWN COMPLETE %| discard(8.4.6)| discard(8.5.1c) | discard(8.5.1c) | discard(8.5.1c) | discard(8.5.1c) | discard(8.5.1c) | discard(8.5.1c) |+4(C) >
+DATA | tabort_8_4_8 | discard(6.0) | discard(6.0) |*eat_data_6_2 | eat_data_6_2 | eat_data_fast4-4| discard(6.0) | discard(6.0)
+SACK | tabort_8_4_8 | discard(6.0) | eat_sack_6_2_1 |*eat_sack_6_2_1 | eat_sack_6_2_1 | discard(6.0) | eat_sack_6_2_1 | discard(6.0)
+HEARTBEAT | tabort_8_4_8 | violation 7| other_stupid 8|*beat_8_3 | beat_8_3 | beat_8_3 | beat_8_3 | other_stupid 9
+HEARTBEAT ACK | tabort_8_4_8 | violation 7| lucky 7|*backbeat_8_3 | backbeat_8_3 | backbeat_8_3 | backbeat_8_3 | backbeat_8_3
+ERROR_stale | discard 4| discard(5.2.6) | do_5_2_6_stale | discard(5.2.6) | discard(5.2.6) | discard(5.2.6) | discard(5.2.6) | discard(5.2.6)
+ERROR | tabort_8_4_8 | ? | ? | ? | ? | ? | ? | ?
+ECNE | bug? | bug? | do_ecne | do_ecne | do_ecne | do_ecne | do_ecne | violation
+CWR | discard | discard | discard | do_ecn_cwr | do_ecn_cwr | do_ecn_cwr | discard | bug?
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Timeouts | | | | | | | |
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+T1-COOKIE TO | bug | bug | do_4_3_reecho | bug | bug | bug | bug | bug
+T1-INIT TO | bug | do_4_2_reinit | bug | bug | bug | bug | bug | bug
+T2-SHUTDOWN TO | bug | bug | bug | bug | bug | do_9_2_reshut | bug | do_9_2_reshutack
+T3-RTX TO | bug | bug | do_6_3_3_retx | do_6_3_3_retx | do_6_3_3_retx | bug | do_6_3_3_retx | bug
+HEARTBEAT TO | bug | bug | bug | do_8_3_hb_err | do_8_3_hb_err | heartoff 5| do_8_3_hb_err | heartoff 5
+SACK TO | bug | bug | bug | do_6_2_sack | do_6_2_sack | do_6_2_sack | bug | bug
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Other Events | | | | | | | |
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+NO PENDING TSN | ignore | ignore | ignore | ignore |*do_9_2_start_shut >| ignore |+do_9_2_shutack 4-6>| ignore
+ICMP UNREACHFRAG | adjust_mtu | adjust_mtu | adjust_mtu | adjust_mtu | adjust_mtu | adjust_mtu | adjust_mtu | adjust_mtu
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+Primitives | | | | | | | |
+-----------------------|---------------|-----------------|-----------------|------------------|--------------------|-----------------|--------------------|-------------------
+PRM_INITIALIZE | | error | error | error | error | error | error | error
+PRM_ASSOCIATE | do_PRM_ASOC >| error | error | error | error | error | error | error
+PRM_SHUTDOWN | error | mark_shutdown 5| mark_shutdown 5|*do_9_2_PRM_SHUT >| discard 5| discard 5| discard(9.2) | discard 5
+PRM_ABORT | error | do_PRM_ABORT <| do_PRM_ABORT <<| do_PRM_ABORT <<<| do_PRM_ABORT >>>>| do_PRM_ABORT >>>| do_PRM_ABORT >>| do_PRM_ABORT >
+PRM_SEND | error | do_PRM_SENDQ6.0 | do_PRM_SENDQ6.0 | do_PRM_SEND | error(9.2) | error(9.2) | error(9.2, 4-5) | error(9.2, 4-7)
+PRM_SETPRIMARY | error | error | do_PRM_SETPRI | do_PRM_SETPRI | do_PRM_SETPRI | do_PRM_SETPRI | do_PRM_SETPRI | do_PRM_SETPRI
+PRM_RECEIVE | error | error | | do_PRM_RCV | do_PRM_RCV | do_PRM_RCV | do_PRM_RCV? | do_PRM_RCV?
+PRM_STATUS | error | get_PRM_STATUS | get_PRM_STATUS | get_PRM_STATUS | get_PRM_STATUS | get_PRM_STATUS | get_PRM_STATUS | get_PRM_STATUS
+PRM_CHANGEHEARTBEAT | error | do_PRM_CH_HB | do_PRM_CH_HB | do_PRM_CH_HB | do_PRM_CH_HB | do_PRM_CH_HB | do_PRM_CH_HB | do_PRM_CH_HB
+PRM_REQUESTHEARTBEAT | error | do_PRM_HB | do_PRM_HB | do_PRM_HB | do_PRM_HB | do_PRM_HB | do_PRM_HB | do_PRM_HB
+PRM_GETSRTTREPORT | error | get_PRM_SRTT | get_PRM_SRTT | get_PRM_SRTT | get_PRM_SRTT | get_PRM_SRTT | get_PRM_SRTT | get_PRM_SRTT
+PRM_SETFAILURETHRESHOLD| error | error | do_PRM_FTHRESH | do_PRM_FTHRESH | do_PRM_FTHRESH | do_PRM_FTHRESH | do_PRM_FTHRESH | do_PRM_FTHRESH
+PRM_SETPROTOPARAMETERS | error | do_PRM_SETPARM | do_PRM_SETPARM | do_PRM_SETPARM | do_PRM_SETPARM | do_PRM_SETPARM | do_PRM_SETPARM | do_PRM_SETPARM
+PRM_RECEIVE_UNSENT | error | ? | ? | ? | ? | ? | ? | ?
+PRM_RECEIVE_UNACKED | error | ? | ? | ? | ? | ? | ? | ?
+PRM_DESTROY | error | do_PRM_DIEDIE | do_PRM_DIEDIE | do_PRM_DIEDIE | do_PRM_DIEDIE | do_PRM_DIEDIE | do_PRM_DIEDIE | do_PRM_DIEDIE
diff --git a/doc/style_guide.txt b/doc/style_guide.txt
new file mode 100644
index 0000000..d5b3bb2
--- /dev/null
+++ b/doc/style_guide.txt
@@ -0,0 +1,195 @@
+This is the style guide for the LKSCTP Project.
+<http://www.sf.net/projects/lksctp/>
+
+1.0 Introduction
+
+Use the Linux kernel coding style as the base,
+linux/Documentation/CodingStyle.
+
+This is intended as the IETF kernel reference code for RFC2960 and the
+SCTP API. As such, readability is paramount. We attempt to follow
+the names from RFC2960 as closely as practical given the constrains of
+C and the Linux kernel naming conventions.
+
+Here are the approximate naming rules we use. Those marked
+[obsolescent] will go away once we purge the last vestiges of them.
+
+1) [obsolescent] If a name appears in RFC 2960 or the API draft we try
+ to use it as closely as permitted by C syntax without ADDING "_".
+ This usually means names of the form "xyzAbc". E.g. "Duplicate TSN"
+ from RFC2960 became "DuplicateTSN", but "a_rwnd" is unaltered.
+
+New names should use this revised rule 1:
+
+ If a name appears in RFC 2960 or the API draft we try to use it as
+ closely as permitted by C syntax without using upper case letters.
+ This usually means names of the form "xyz_abc". E.g. "Duplicate
+ TSN" from RFC2960 became "duplicate_tsn", but "a_rwnd" is
+ unaltered. Remember the acronyms still need to be upper case in
+ comments.
+
+2) [obsolescent] If a name refers to a struct which appears on the wire we use
+the form "struct xyzAbc". This is historically because we inherited most
+of these from the user space implementation. E.g. "struct sctpHeader".
+
+3) There is no rule 3.
+
+4) All functions start with "sctp_". Uh, yeah, well, uh...
+
+5) Constants have the form "XYZ_ABC" per K&R.
+
+6) [obsolecent] If "XYZ" is an acronym it SHOULD be capitalized as in
+ "XYZ_abc" or "XYZabc" unless overridden by rule 2 or rule 4. E.g.
+ "struct SCTP_association".
+
+New names should use this revised rule 6:
+
+ Names with anronyms SHOULD map them to lower case, E.g.
+ "struct sctp_association".
+
+7) All remaining names SHOULD use the form "xyz_abc". E.g. "int too_big".
+
+8) Deviations from these rules are bugs and need to be fixed.
+
+
+2.0 Architectural and Procedural Standards
+
+The core metaphors are the state machine (sctp_do_sm(), related
+functions) and the smart pipe (inqueue, outqueue, ULPqueue, packet).
+
+The state machine breaks down into a pure functional core,
+sctp_sm_statefuns.c, with no side effects, and an explicit set of side
+effects, sctp_sm_sideeffects.c.
+
+Every function, typedef, enum, and struct needs a descriptive comment.
+
+3.0 /* Comments */
+
+Except as noted below, make all comments full sentences.
+
+Proper behaviour is to spell-cheque your comments. Those colourful
+American spellings will not be rejected.
+
+Start all sentences with a capital letter. Do not begin sentences
+with symbols which must be all lower case. Sentences end with a
+period, question mark, or exclamation point. Punctuation at the end
+of a sentence has two trailing spaces or a trailing newline.
+
+Comments should confine themselves to expressing the INTENT of the code.
+
+If comments do not agree with the code, then we have a BUG.
+
+Passive voice should be avoided.
+
+Every function, typedef, enum, and struct needs a descriptive
+comment.
+
+/* All comments are C comments, */
+// not C++ comments.
+
+/* Multiline comments should
+ * look like this.
+ */
+
+Every #endif should include a comment describing the matching #if.
+E.g.
+
+#if 0
+#endif /* 0 */
+
+A struct sk_buff_head needs a comment describing the REAL type of its
+elements.
+
+To disable a section of code use
+#if 0
+#endif /* 0 */
+rather than /* */. The if/endif pair safely interoperates with
+existing comments.
+
+4.0 Appearance & Pretty printing
+
+Put a space after every keyword.
+
+Here is an example function:
+
+retval_t my_fun(int foo, struct SCTP_struct *bar)
+{
+ statement;
+}
+
+Every switch statement should have a default clause. If the default
+can never happen, default should crash or otherwise report failure.
+
+A loop with no body looks like this:
+
+ while (test()) {
+ /* Do nothing. */
+ }
+
+If a compound condition or arithemetic expression extends beyond the
+79 character limit, put the operators at the end of the line. E.g.
+
+ if ((NULL == map->tsn_map) ||
+ (NULL == map->overflow_map) ||
+ (map->len == 0)) {
+...
+
+
+The if/else style must follow that of K&R style, for example:
+
+ if (foo) {
+...
+ } else {
+...
+ }
+
+Unrequired whitespace should be removed from the end of lines and end of
+file. Hardtabs should be used where possible.
+
+
+5.0 Compiler and Behavior issues
+
+When comparing a constant to a variable, put the constant on the
+left. The compiler will tell you if you ommited a '='. E.g.
+
+ if (MY_CONSTANT == var) {
+ whatever();
+ }
+
+Please eliminate all compiler warnings. "Compilation errors are, in a
+way, unit test failures of their own. They tell us that the
+implementation does not match the specification." -- check.sf.net tutorial
+
+Please make forward declarations for all functions in the appropriate
+header files. This helps us detect interface changes.
+
+Whenever practical, allocate a large block of memory OUTSIDE a loop
+and then populate it inside the loop, rather than allocating many
+small blocks inside the loop.
+
+Do not use #ifdef TEST_FRAME unless absolutely necessary. In
+particular, if you simply call kernel functions which are not defined
+in the test frame, please add them to the test frame. The only case
+we know of which is difficult to handle is static inline functions.
+
+We require using this style of initialization:
+
+struct in_ifaddr eth2_ifa =
+ {.ifa_next = NULL, .ifa_dev = NULL, .ifa_local = 0, .ifa_address = 0};
+
+Keyword initializations are less susceptible to bugs due to changes in
+the underlying structures.
+
+
+6.0 Version changes
+
+The lksctp-tools packages uses the "M.m.p" versioning model for both
+the package itself & the provided shared libraries:
+
+- (M)-ajor revision change means both source & binary incompatibility
+ (user source code change might be required)
+
+- (m)-inor revision change means source compatibility, while ABI might
+ not be preserved (rebuild is required)
+
+- (p)-atchlevel change means that both API & ABI are preserved.
diff --git a/doc/template.c b/doc/template.c
new file mode 100644
index 0000000..a42afec
--- /dev/null
+++ b/doc/template.c
@@ -0,0 +1,47 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * This file is part of the SCTP kernel Implementation
+ *
+ * $Header: /home/CVS/tsp/SCTP/sctp-tools/doc/template.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+ *
+ * These functions frob the sctp nagle structure.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+static char *cvs_id __attribute__ ((unused)) = "$Id: template.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $";
+
+#include <net/sctp/sctp.h>
diff --git a/doc/what_we_were_doing.txt b/doc/what_we_were_doing.txt
new file mode 100644
index 0000000..6a2834a
--- /dev/null
+++ b/doc/what_we_were_doing.txt
@@ -0,0 +1,981 @@
+What were we doing when we stopped?
+funtest1.c
+ test_sendto()
+ Wed Sep 27 12:48:34 CDT 2000
+ We are about to write sctp_do_prm_asoc().
+
+ Thu Sep 28 15:58:27 CDT 2000
+ DONE
+
+ test_run_network()
+ Thu Sep 28 21:37:51 CDT 2000
+ We are testing. The first chunk we see in outqueue
+ has a chunkID of 0 (DATA), not 1 (INIT). It also has
+ a length of 0. It looks like a dummy chunk.
+
+ Next thing will be struct SCTP_inqueue. We WILL
+ produce an automated test for that structure!
+
+ Fri Sep 29 19:41:21 CDT 2000
+ We fixed the bug mentioned above.
+ We have created a unit test for SCTP_inqueue.
+ Next, we should implement SCTP_inqueue.
+
+ Mon Oct 2 11:03:10 CDT 2000
+
+ Mon Oct 2 18:07:14 CDT 2000
+ Finishing up on test_inqueue. Currently giving
+ bad results for the chunk header for the second
+ chunk popped. Also need to clean up validate_queue's
+ type-casting to make the warning go away.
+
+ Wed Oct 4 10:51:55 CDT 2000
+ We have fixed the warning. Still working on the 2nd chunk.
+
+ Wed Oct 4 14:06:21 CDT 2000
+ We passed our first automated unit test!!!
+ sctp_bundle_out() needs writing.
+
+ Wed Oct 4 16:36:10 CDT 2000
+ writing sctp_bundle_out()
+ writing ip_queue_xmit()
+ trying to find out how to call sctp_v4_rcv()
+ Thu Oct 5 18:40:49 CDT 2000
+ We believe that ip_queue_xmit() is "written".
+ We think sctp_bundle_out() is written.
+ We are stepping through test_run_network(),sctp_v4_rcv()
+ We have made it out to ep_put(), near the end of
+ sctp_v4_rcv().
+ bh_[un]lock_ep(), ep_put() need writing.
+ We plan to continue through sctp_v4_rcv().
+ GOAL: return from test_run_network() by COB Friday
+
+ Fri Oct 6 18:29:01 CDT 2000
+ Gee! We are calling ourselves forever! We need to
+ break this cycle by implementing bottom half/top
+ half... Welcome to the kernel!
+
+ On the upside, we made it back up into do_5_1B_init().
+ Fix the BUG BUG BUG at the end of ip_queue_xmit().
+
+ Mon Oct 9 12:17:59 CDT 2000
+ We believe test_run_network() is written--we have
+ completed on full loop.
+
+ Here is what we expect in the next three iterations:
+Next loop:
+ ep2: send the INIT_ACK
+ ep1->asoc: process the INIT_ACK, enter COOKIE_ECHOED, queue COOKIE_ECHO
+ueber-next loop:
+ ep1->asoc: send the COOKIE_ECHO, send the DATA
+ ep2->asoc: process COOKIE_ECHO, make asoc in ESTABLISHED, queue COOKIE_ACK
+ process DATA, queue SACK
+ueber^2-next loop:
+ ep2->asoc: send COOKIE_ACK, SACK
+ ep1->asoc: process COOKIE_ACK, enter ESTABLISHED, process SACK,
+ free DATA
+
+ Mon Oct 9 18:53:44 CDT 2000
+ The test for SCTP_outqueue now fails! Yay!
+ Mon Oct 9 20:41:36 CDT 2000
+ The test for SCTP_outqueue now passes! Yay!
+
+ Goal for tomorrow: Return from test_run_network().
+ Continue through the loop...
+
+ The DATA packet is ending up in the endpoint queue, not the
+ assoication queue.
+ Tue Oct 10 15:26:54 CDT 2000
+ Fixed. This is correct behaviour, but now we look for
+ the association AGAIN.
+
+ The TSN is not getting set. This should happen in the
+ SCTP_outqueue.
+ Tue Oct 10 15:55:27 CDT 2000
+ Added a test to test_outqueue for TSN fix.
+ Yay, test_outqueue fails!
+
+ Added a test to test_inqueue for the end-of-packet
+ callback feature.
+ Tue Oct 10 17:32:53 CDT 2000
+ Passing test... We are now using the feature in sideeffects.c.
+ Are we getting a SACK now?
+ Tue Oct 10 18:58:25 CDT 2000
+ Yes! We ARE getting a SACK! Yahoo!
+
+ Plan for tomorrow: sctp_recvmsg(), sctp_send_up(). This is
+ probably a new data struture...
+
+ Wed Oct 11 14:21:32 CDT 2000
+ Yes, it is several... 7? Sigh.
+ Yay! test_ULPqueue fails!
+
+ Wed Oct 11 16:56:06 CDT 2000
+ DANGER, WILL ROBINSON! NOT ALL UNIT TEST PASS! But the day
+ is over and piggy needs to leave...
+ WRITE sctp_ULPqueue.c:sctp_ULP_chunk2event()
+
+ Thu Oct 12 12:08:23 CDT 2000
+ Put SCTP and IP headers on the test chunk. Make sure that
+ skb->data, however, points at the actual payload.
+
+ Thu Oct 12 15:40:00 CDT 2000
+ test_ULPqueue passes! Yahoo!
+ Back to funtest1...
+
+ options for things that changed which might corrupt the
+ MD5digest:
+ do_gettimeofday() replaced get_time()
+ tv_add() replaced net_profile_add()
+ get_random_bytes() replaced net_random()
+ I switched to MD5 and the problem disappeared. This is very
+ bad. The problem is that the SLA1 code is overruning the
+ stack and creaming its parent's variables. Specifically,
+ context->howManyInBlock is getting above 64 (the size of the
+ block). This causes "leftToFill" to become negative at line
+ 195 and then things really fall apart. This looks like a bug
+ to me, but it worked before...
+
+ Fri Oct 13 10:14:37 CDT 2000
+ Goal for today: Get through ueber^2-next loop.
+
+ Don't forget to look for that COOKIE ACK...
+
+ Fri Oct 13 16:52:11 CDT 2000
+ We have delivered a data packet all the way to the user from
+ the other user! We do not seem to have either a COOKIE_ACK OR
+ a SACK. Such is life... More to do... We do not deliver the
+ COMUP event either...
+
+ We sort of deliver the COMMUNICATION_UP message. What a WASTE.
+
+ We REALLY need to get back to COOKIE_ACK/SACK. By early next
+ week we MUST be all the way to SHUTDOWN_ACK.
+
+ Mon Oct 16 12:19:18 CDT 2000
+ We DID see that COOKIE_ACK/SACK. We have received three
+ packets. Check to make sure we got the second SACK.
+
+ Goal for today: Generate a SHUTDOWN. This means a new event
+ type for the state machine: OTHER.
+
+ Mon Oct 16 15:11:16 CDT 2000
+ We have finished sctp_close().
+
+ Mon Oct 16 20:52:42 CDT 2000
+ We got a SHUTDOWN processed.
+
+ The NO PENDING TSN event needs to be scheduled so that it
+ happens AFTER all the side effects for the PRIOR event.
+
+ Refactor the SACK processing OUT of sctp_outqueue.c--use the
+ empty handler. REMEMBER TO WRITE THE TEST FIRST!
+
+ Once all that works, continue on to generating SHUTDOWN ACK.
+
+ Goal for tomorrow: pass empty handler test, get back to the
+ point in the functional test where we are ready to generate
+ SHUTDOWN ACK.
+
+ Stretch goal for tomorrow: Get to the end of the functional test.
+
+ Tue Oct 17 11:39:00 CDT 2000
+ We added sctp_delayed_side_effects() where we can execute side
+ effects which MUST happen after all other side effects are
+ processed.
+
+ The test for the empty queue feature now fails!
+
+ Tue Oct 17 11:54:51 CDT 2000
+ The test for the empty queue feature now passes!
+
+ We have decided to put this off until post-Bakeoff:
+ Refactor the SACK processing OUT of
+ sctp_outqueue.c--use the empty handler. REMEMBER TO
+ WRITE THE TEST FIRST!
+ P.S. We DO use the empty handler now, but SACK processing is
+ still partially embedded in outqueue.
+
+
+ DONE: sctp_do_9_2_final() should generate an event to send to the
+ ULP...
+ DONE: We need to deal with the possibility of an association
+ unlinking in the middle of an SK_FOR.
+ If there are undelivered notifications in association, delay
+ its freedom.
+
+ Tue Oct 17 18:17:07 CDT 2000
+ We completed the full protocol negotiation in funtest1.c!
+ Yahoo!
+ DONE: All that remains is to keep the association around
+ long enough to deliver the final notification.
+ DONE: Also, sctp_do_4_C needs to generate a ULP event too...
+ The three major tools... No, four...
+
+ Goal for tomorrow:
+ 1) Running functional test by lunch time.
+ 2) Make the kernel link.
+
+ Wed Oct 18 10:42:40 CDT 2000
+ We now set the destination address correctly. (We think...)
+
+ Wed Oct 18 12:42:05 CDT 2000
+ The unit tests run again. Setting destination addresses broke
+ a couple of them...
+
+ Wed Oct 18 14:45:26 CDT 2000
+ Yeehaw! The functional test passes!
+
+ Wed Oct 18 15:23:26 CDT 2000
+ The kernel links!
+
+ Tasks:
+ Write a kernel functional test. Make it fail.
+ Write sctp_sendmsg().
+ Register all the SCTP structs in the right places...
+ Move funtest1.c:test_run_network functionality into the
+ kernel.
+
+ Wed Oct 18 16:44:30 CDT 2000
+ funtest2 now fails! Yay! It features cool error messages...
+
+ goals for tomorrow:
+ DONE: 1) Write sctp_sendmsg().
+ DONE: 2) Register all the SCTP structs in the right places...
+
+ Thu Oct 19 12:09:43 CDT 2000
+ We have a first draft of sctp_sendmsg().
+ DONE: Write lower level functions for sctp_sendmsg().
+ DONE: Fix the retval misuses in sctp_recvmsg().
+ DONE: Check all of sctp_socket.c for user space memory references.
+
+ Thu Oct 19 18:10:27 CDT 2000
+ FIXED: We are failing to generate SACKS. It appears that pop_inqueue
+ is deciding that eop is not happening for data chunks.
+
+ Thu Oct 19 21:32:36 CDT 2000
+ It appears that at least the three key structures (sctp_prot,
+ sctp_protocol, and inet_seqpacket_ops) are properly
+ registered.
+
+ We also sort of fixed a problem with queue_xmit--it needs to
+ be transport specific. We still do not set it properly in the
+ transport structure, but as a hack, we steal it from the ep.
+
+ goals for Friday:
+ 1) Move funtest1.c:test_run_network functionality into the
+ kernel.
+ 2) Have a real kernel panic!
+ 3) Move the repository onto one of the laptops...
+
+
+ Fri Oct 20 18:23:43 CDT 2000
+ test_inqueue now fails after changing handler handling
+ (i.e. item 1 above)!
+
+ Fri Oct 20 18:39:30 CDT 2000
+ test_inqueue now passes! (as do test_outqueue & test_ULPqueue)
+ funtest1, anyone?
+
+ We refactored to get rid of sctp_sm_delayed_sideeffects().
+ This led to outqueue empty processing getting a LOT cleaner.
+ This also forced us to fix the empty test in test_outqueue and
+ feed it a REAL(ish) SACK. This led us in turn to a VERY
+ subtle TSN bug. XP RULES! YOW YOW YOW!!!!
+
+ Fri Oct 20 23:28:57 CDT 2000
+ We passed the functional test and all the unit tests. We
+ think we have something we MIGHT be able to link into a kernel
+ and test...
+
+ 3) Move the repository onto one of the laptops...
+
+ Goal for Monday:
+ 2) Have a real kernel panic!
+
+
+ Tue Oct 24 16:10:44 CDT 2000
+ Still no kernel panic, but we have some things which seem to work! Yowza!
+
+ Specifically, sctp_socket(), and sctp_bind() appear to work. We get an
+ -EFAULT when we call sctp_sendmsg(). In sctp_recvmsg() we had a hang.
+
+ Tue Oct 24 16:57:05 CDT 2000
+ unit tests pass (again)! Yahoo!
+
+ Wed Oct 25 10:57:59 CDT 2000
+ funtest3 rewritten to use getopt and support addresses other
+ than the loopback.
+ Wed Oct 25 11:47:18 CDT 2000
+ funtest3 --listen fails!
+
+
+ Thu Oct 26 00:18:43 GMT-6 2000
+ Why are we getting EINVAL?
+ - We are certain that the address going to bind is in kernel space.
+ - Add the endpoint port--we wish to differentiate the two
+ possible failures.
+
+ Wed Oct 25 16:38:56 CDT 2000
+ We are setting the peer's port to network byte order in one or
+ both of the following: sctp_create_asoc(), sctp_add_transport().
+ We are trying to make funtest1 pass again...
+
+ We are trying to not panic in funtest3 --listen.
+
+ Thu Oct 26 14:23:08 CDT 2000
+ Created the macro DEBUG_PRINT() and a matching unit test
+ (foolishly put in funtest1.c...). It failed! It passes!
+
+ By the end of the day we completed a full INIT-DATA-SHUTDOWN
+ sequence with the user space refimpl! We listened and the
+ usref initiated.
+
+ Fri Oct 27 08:46:41 CDT 2000
+ Goal for today: Do the equivalent of funtest2 with funtest3
+ (interoperate both directions with the usref).
+
+ Fri Oct 27 10:13:39 CDT 2000
+ funtest3 --send fails!
+
+Tue Jan 16 01:54:34 CST 2001
+ We have two bugs:
+ 1) Line 277 in sctp_endpointola.c.
+ 2) We need to handle non-existent ep properly, almost
+ everywhere.
+ We need to add a blow-away-the-endpoint test to one of the
+ functional tests.
+
+Wed Jan 17 02:19:18 CST 2001
+ We fixed bug 1, and now cherish bug 2 wholeheartedly.
+
+ We don't (?) need a blow-away-ep test, but we eventually need
+ to work on the out-of-the-blue-packet story.
+
+ We now pass funtest1 and funtest1b (Yeah!).
+
+ Next up: funtest3 with back to back associating, and (dare we
+ hope?) funtest2. (Note: _No_ _work_ will be done to fix
+ funtest2 until after the Developers' Release.)
+
+Tue Jan 30 16:00:26 CST 2001
+ We have a simple-minded merge of our SCTP changes into 2.4.1.
+ This merely resolved the conflicts--tag 'linux-2_4_1+sctp' will
+ NOT compile. We need to do all the data structure changes.
+
+
+Tue Feb 27 20:07:52 CST 2001
+
+In the middle of getting funtest1 to work (again), test_print_message
+prints a bad type for a message. May be a related CORE_DUMP in there
+somewhere too...
+
+Fri Mar 2 20:50:22 CST 2001
+
+We believe that sctp_flush_outqueue is pretty-much ready except for
+starting the timers. We need to stop the timers in
+need to generate the timeouts (
+
+6.3.2 R2 tells us to turn off T3-rtx when we get acks for all data on
+ an address...
+
+We REALLY want a per-transport transmitted queue. What we want to do
+is a outqueue-private component of the transport data structure.
+
+DONE: PLAN FOR MONDAY: Make a release w/o lost_data packet.
+PLAN FOR Wednesday after next: Release including lost data packet and
+whatever else we jam in...
+
+DONE: Write a unit test for bundling.
+Pass the unit test for bundling.
+Make the transmitted queues transport based because we need a per
+transport timer which gets turned off when there is nothing in flight.
+Make ft_frame_lostpacket pass.
+
+Tue Mar 13 19:44:27 CST 2001
+We are working on getting test_outqueue to work again, this time with
+bundling. The code compiles, but still dumps core. It looks like a
+bug in the test frame (q->asoc is NULL).
+
+Wed Mar 14 14:07:51 CST 2001
+The unit tests (including the bundling mods for test_outqueue) pass.
+The mods were to comment out sock_hold in the set_owner..., since it
+kept landing us in the real kernel code (asm/atomic.h). We thought
+this was due to string.h, but that gets called in somewhere magically
+too.
+
+Final mod was an if around the last sctp_transmit_packet for when the
+payload size isn't > 0. I (KK) added a catcher for payload_size < 0.
+
+Now on to making the transmitted queues transport based.(?)
+
+Wed Mar 14 16:26:59 CST 2001
+Have added transmitted (not private) to SCTP_transport and initted in
+sctp_add_transport(). Next would be sctp_flush_outqueue().
+
+Thu Mar 15 19:15:24 CST 2001
+Whew. We added transport-transmitted to sctp_empty_outqueue(),
+sctp_flush_outqueue() and sack_outqueue(). We also took the
+check-transmitted-queue logic out of sctp_sack_outqueue() and added
+sctp_check_transmitted().
+
+We also isolated a wacky SK_FOR behavior that had us stumped for a
+while. If you pass a local variable to SK_FOR as the_list, it has
+trouble ending the for loop since the local variable is on the stack
+(for the calling function), but the end iteration for the for"ing"
+(the real the_list) would be whereever it was before being copied into
+the local variable.
+
+Anyhow, the unit tests pass (although we haven't committed yet.)
+
+Fri Mar 16 19:19:01 CST 2001
+We fixed a padding problem with the bundling code (and its attendant
+problems with the ULPqueue/recvmsg code). The unit tests and all
+ft_frame tests (except lostpacket, naturally) pass! Have not run
+ft_kernel_basic yet. Despite this, I'm committing, since La Monte and
+I(KK) will be at the IETF next week. I also need to remember to put
+Perry's name in the code he's worked on.
+
+
+Mon Mar 19 17:31:37 CST 2001
+We were creating a new kind of smart pipe, the SCTP_packet. Stuff
+packets in the top until they transmit.
+
+Tue Mar 27 11:26:26 CST 2001
+Write the unit test for SCTP_packet.
+
+Fri Apr 6 01:18:32 CDT 2001
+We THINK we have a full implementation of the sockets protocol table.
+We will have a go at integrating af[6]_inet.c into our test frame so
+we can write tests for it...
+
+Tue Apr 10 11:39:13 CDT 2001
+Finish SCTP_packet today.
+
+Tue Apr 10 21:39:25 CDT 2001
+Yeah, right.
+
+OK, we're in the middle of transforming transmitted_queue and
+sacked_queue into struct list_head's so that we can avoid copying
+chunks when putting them in packets.
+
+What remains:
+DONE: Make test_outqueue compile.
+UNDONE: Make test_outqueue fail.
+DONE: Finish transforming SCTP_outqueue to the new interfaces.
+DONE: Make test_outqueue pass.
+
+DONE: Make test_packet compile.
+DONE: Make test_packet fail.
+DONE: Write SCTP_packet (sctp_output.c).
+DONE: Make test_packet pass.
+
+DOING: Get on with lost packet.
+
+Wed Apr 11 16:38:52 CDT 2001
+Yay! We have test_outqueue passing...
+
+Thu Apr 12 10:23:01 CDT 2001
+Goal for today: Make test_packet compile and fail.
+Do an intermediate commit.
+
+Thu Apr 12 16:56:53 CDT 2001
+We hit our goal for the day!
+We've just finished the horrible table in sctp_append_chunk().
+We need to write sctp_transmit_packet().
+
+Mon Apr 16 10:39:27 CDT 2001
+DONE: Goal for the day: Get all unit tests to pass (test_packet being the
+current red-headed-stepchild.)
+
+Mon Apr 16 15:36:42 CDT 2001
+Yay! We've hit today's goal!
+
+Mon Apr 16 17:22:44 CDT 2001
+Milestone: all ft_frame passes except lostpacket (Almost out of the
+refactoring quagmire...).
+
+Mon Apr 16 19:12:37 CDT 2001
+Milestone: ft_frame_lostpacket now fails (after being rewritten a bit).
+
+SKIPPED: Fix up the statefun retval to communicate timer updates properly.
+DONE: Start the rtx timer.
+DONE: Make sure the rtx timer set/clear events are generated by the
+ appropriate state functions.
+DONE: Create the rtx timeout state function.
+Update the side effects to:
+ SKIPPED: Process rtx timer updates.
+ DONE: Move chunks from transmitted to retransmit.
+ DONE: Call flush with rtx_timeout set.
+
+Plan for tomorrow:
+DONE: Create the timeout event.
+DONE: Make ft_frame_lostpacket pass.
+DONE: Run ft_kernel_basic, make it pass.
+DONE: Run sctp_darn tests. (They failed, though...)
+
+Tue Apr 17 17:27:15 CDT 2001
+ft_frame_lostpacket passes! Yeeha!
+
+Tue Apr 17 19:01:22 CDT 2001
+ft_kernel_basic passes--insignificant changes needed for compilation.
+
+Wed Apr 18 14:58:30 CDT 2001
+DONE: Write ft_frame_evenpackets.
+DONE: Have it compile and fail.
+DONE: Write sack timer support code.
+DONE: Have it compile and succeed.
+
+Wed Apr 18 16:36:17 CDT 2001
+We did a small refactoring where we changed most instances of
+struct timeval into jiffies. We can't do this for every struct timeval
+since sk->stamp is a struct timeval and we use this to check cookie
+lifetimes. C'est la vie. So geht es in Leben.
+
+ft_frame_evenpackets fails! Yeeha!
+All unit tests pass!
+
+Thu Apr 19 10:34:04 CDT 2001
+Goal for morning: ft_frame_evenpackets passes.
+To make it pass, the sack timer should be:
+DONE: - initialized
+DONE: - started
+DONE: - stopped
+DONE: - event (expiration)
+DONE: - state function
+
+DONE: - sctp_do_timerWork
+
+Thu Apr 19 13:17:08 CDT 2001
+We've written the sack timer code and it compiles, but the ft still
+fails.
+
+Thu Apr 19 15:39:58 CDT 2001
+ft_frame_evenpackets passes! Yay!
+
+What we need to do for multihoming:
+DONE: Extend test frame for multilink.
+Write ft_frame_lostlink.
+Make ft_frame_lostlink compile.
+Make ft_frame_lostlink fail.
+Write multi-homing support:
+- Add counter events to OTHER table
+- Stroke error counts (8.2)
+DONE: - Write sctp_bindx() (API 8.1)
+- Clear error counter when RTX timer is stopped. (8.2)
+- Do failover state function (8.2, 6.4.1)
+- Do failover side effects
+- Change sctp_transmit_packet() to modify the socket for the chosen
+ destination address.
+- Change transport selection to skip inactive destinations (bakeoff 3.6)
+Make ft_frame_lostlink pass.
+
+Thu Apr 19 23:01:11 CDT 2001
+We need to refactor the whole INIT/INIT ACK/COOKIE ECHO startup
+sequence to make the INIT header processing more symmetric. In
+particular, we are going to put the whole INIT chunk (with all
+parameters) into the cookie and simplify the cookie as much as
+possible. This allows both sides to take a skeletal association and
+an INIT packet and build a full association.
+
+Check whether the initial destination address needs to be
+automagically added to the list of IP addresses for the association.
+
+Fri Apr 20 17:28:42 CDT 2001
+We're in the middle of the aforementioned refactoring. We are working
+our way through the function do_5_1B_init(). Credo that
+sctp_make_temp_asoc() is now properly rewritten. Next to rewrite is
+sctp_make_init_ack().
+
+tar up THIS directory heirarchy
+copy to both laptops
+check out the most recent CVS'd stuff on both laptops
+
+
+Sat Apr 21 18:31:28 CDT 2001
+I'm in the middle of sctp_unpack_cookie(). Make sure that everything
+lines up properly... I THINK the static parts of the INIT are still
+unaccounted for. Maybe. Maybe not... No, I think those are part of
+asoc->c, in which case, they are properly handled.
+
+Check that we do all three passes through the variable-length
+parameters: INIT, INIT ACK, COOKIE ECHO (INIT is in the cookie).
+
+Sun Apr 22 01:46:21 CDT 2001
+See the FIX ME in sctp_unpack_cookie();
+
+Tue Apr 24 16:43:30 CEST 2001
+sctp_make_cookie_echo() in sctp_side_effects() returns a malformed chunk.
+
+Thu Apr 26 10:44:15 CEST 2001
+We have a buildable kernel and we pass all unit and functional tests
+except ft_frame_lostlink. ft_kernel_basic remains untested. The plan
+for today is to get some interop test run with Sun and perhaps some
+others...
+
+Thu Apr 26 18:36:54 CEST 2001
+We have a deadly INIT packet from Sun. We are trying to make a test
+frame from the deadly packet.
+
+Added WORD_ROUND() to sctp_addto_chunk() to support correct parameter
+bounding...
+
+Added some infrastructure to support replacing arbitrary packets in a
+transaction. This doesn't work yet and isn't quite as flexible as we
+really want.
+
+Fri Apr 27 11:34:22 CEST 2001
+Start the SSN at 0, not 1.
+Increment the SSN.
+
+Tue May 1 16:11:17 CDT 2001
+These are the changes that piggy made on the airplane from Nice:
+
+DONE: Do duplicate checking in sctp_bind_endpoint().
+
+DONE: Add struct bare_ip_sctp_packet.
+
+DONE: Modify CHUNK_TYPE() so that it can work even if an IP header is present.
+
+DONE: Fix the calls to CHUNK_TYPE(). The first call is on an IP packet with
+ a header.
+
+Wed May 9 15:39:23 CDT 2001
+
+Implement Jon Grimm's suggestion about sctp_init().
+
+DONE: 1. Take the sctp_proto_initted check out of sctp_get_protocol().
+
+DONE: 2. Call module_init(sctp_init) at the end of sctp_protocol.c
+ (Less random, but more thoughtful, placement.)
+
+DONE: 3. Modify the frame tests to call sctp_init() directly.
+DONE: 4. Test the simulated daylights out of it.
+UNDONE: 5. Test the living daylights out of it.
+
+
+Wed May 9 16:41:47 CDT 2001
+DONE: Include <sys/sctp.h> from sctpConstants.h.
+DONE: Go through sctpConstants.h looking for stuff needed by the user and
+ moving it to sys/sctp.h.
+DONE: Go through sctpEvent.h looking for stuff needed by the user and
+ moving it to sys/sctp.h.
+DONE: Test the simulated daylights out of it.
+DONE: Test the living daylights out of it.
+
+Thu May 10 11:55:57 CDT 2001
+We moved kernel/include/sys/sctp.h to linux/include/linux/sctp.h. The
+kernel does NOT have an include/sys/ directory, and
+include/linux/tcp.h has sortof similar semantics...
+
+Move linux/include/linux/sctp.h to kernel/include/net/sctp/sctp_user.h
+and copy THAT to kernel/usr_include/netinet/sctp.h.
+
+Thu May 10 16:34:35 CDT 2001
+Here are all the horrible places we need to put "132":
+DONE: /usr/include/linux/socket.h
+DONE: /usr/include/linux/in.h
+DONE: /usr/include/netinet/in.h
+These are all in kernel/usr_include and kernel/Makefile has been
+modified appropriately.
+
+DONE:Tomorrow: Describe the hijack attack in detail in an email message to
+ Randy and Qiaobing.
+
+Fri May 11 15:43:46 CDT 2001
+Next possible tricks are to work up tests for the SACK processing/RTX
+work, the spicy INIT, or ft_frame_lostlink.
+
+We will extend ft_frame_lostpacket to include multiple lost packets
+and we will have it check reordering.
+
+Wed May 16 14:50:29 CDT 2001
+First pass priority list: Develop tests for these bugs encountered at
+the 3rd bakeoff. (For Wednesday, go for the low hanging fruit.)
+
+BUG: We ignore ABORT.
+TRACE: compaq3_paddedinitackOK.tcp
+TEST: ft_frame_abort
+
+BUG: We will send extra data before we get a COOKIE ACK...
+TRACE: datakinectics_2
+ We really lucked out and this implementation ran fine...
+TEST: <ft_frame_delayed_cookie_ack, this involves adding a packet
+ delay queue to the network simulation>
+
+BUG: We have an INIT that causes an oops.
+TRACE: sun (lost trace)
+TEST: ft_frame_init_bomb
+
+BUG: This INIT ACK causes an oops.
+TRACE: telesoft2_lostsendings.tcp, telesoft3_spicyinitack.tcp
+TEST: <new test: modified ft_frame_init_bomb>
+
+BUG: We don't gap ACK.
+BUG: We retransmitted a TSN which they had gap ack'd.
+TRACE: datakinectics_3, ulticom_3
+TEST: <extend ft_frame_lostpackets to add tests for gap acking>
+
+BUG: We produce MANY SACK's in a row. Bleah. This isn't officially
+ a bug. Is it legal for us to look ahead in our input buffer?
+ Well, Stevens thinks that this is correct behaviour. We should
+ NOT look ahead in our input buffer.
+TRACE: adax2_goodsend.tcp
+TEST: no test needed
+
+BUG: We did not bundle retransmissions.
+TRACE: adax2_goodsend.tcp
+TEST: <modify ft_frame_lost_packets, catch the retransmissions and
+ inspect them on the wire (in Internet[]).>
+
+Mon May 21 15:56:47 CDT 2001
+Today and Tuesday are SCTP days. (Like Crazy Days, only more SCTP and
+less street fair.)
+
+Write the ABORT test.
+
+Tue May 22 18:49:51 CDT 2001
+Once again, we are changing the end-of-packet handling to solve some
+nasty problem. There are two issues here:
+FIXED: - sctp_tq_sideeffects is global and very dangerous (i.e. wrong)
+FIXED: - sctp_gen_sack can be called on an aborted association--it
+ still has a pointer to the free'd memory...
+
+Solution:
+We are marking the last chunk in a packet as the final chunk.
+DONE: - Add the eop flag to SCTP_chunk.
+DONE: - Set the eop flag for the final chunk (sctp_pop_inqueue()).
+DONE: - Initialize the eop flag when we create a new chunk (sctp_chunkify()).
+DONE: - Add gensack to the retval structure.
+DONE: - Modify the data state function to set retval->gensack if eop is set.
+
+DONE: - Set up gensack side effect.
+DONE: - Fix up the prototype for sctp_gen_sack().
+
+DONE: - Create asoc->sack_needed.
+DONE: - Dispose of asoc->peer.dataSeen
+DONE: - Dispose of asoc->counters[SctpCounterAckState]
+DONE: - Dispose of chunk->counted
+
+DONE? - Dispose of sctp_tq_sideeffects and friends.
+DONE: -- call sctp_other_no_pending_TSN() from sctp_side_effects().
+DONE: -- eliminate handlers.empty, etc...
+
+Wed May 23 14:43:44 CDT 2001
+Pass the rest of the ABORT test. This means we want to GENERATE
+aborts. This is the function tabort_8_4_8.
+
+Since we need to generate ABORTs in the CLOSED state, we want to have
+a way to send them without having to build a temporary association.
+
+We will generate a packet for this purpose
+and will call sctp_transmit_packet() on it at the appropriate time.
+
+DONE: - extract relevant data from chunk and endpoint.
+DONE: - change sctp_init_packet to not require the association.
+- build packet
+DONE: - build transport
+DONE: -- refactor sctp_add_transport() to create a sctp_make_transport().
+DONE: --- Add fields for storing af_specific in proto.
+DONE: --- Initialize the af_specific parts of proto.
+DONE: --- Add a mechanism for fetching af_specific from proto.
+DONE: - add retval->packet
+DONE: - add retval->packet handling to SCTP_DISPOSITION_DISCARD.
+DONE: - add prototype for sctp_get_af_specific()
+DONE: - add prototype for sctp_make_transport()
+DONE: - fix call to t_new()
+
+DONE: - Update the state tables to call tabort.
+
+Tue May 29 11:53:18 CDT 2001
+We are applying Jon Grimm's patch.
+DONE: - Edit patch
+DONE: - Apply patch
+DONE: - Add Jon's contact info
+DONE: - unit_test
+DONE: - frametest
+
+Add Xingang Guo's patch.
+DONE: - Edit patch
+DONE: - Apply patch
+DONE: - Check the lock coverage paths
+
+Main changes from patch:
+-- sctp_{lock|release}_sock()
+-- moved locking in sctp_sendmsg() to right before looking up association
+-- checking return values of copy_{to|from}_user
+-- goto out_unlock for EVERY setting of err in sctp_sendmsg()
+-- sctp_setsockopt() had returns with locked socket.
+
+DONE: - Update copyright and credits
+DONE: - is emsg->msg_flags properly initialized somewhere?
+ -- Yes, but it might not conform to the API draft...
+DONE: - unit_test
+DONE: - frametest
+
+DONE: - kerneltest
+
+DONE: - Make new release
+DONE: - publish release to Source Forge.
+DONE: - Send note to list detailing changes to Xingang's patch...
+
+Thu Jun 14 17:41:04 CDT 2001
+A plan for patch application. We have 5 patches:
+
+jgrimm_delayed_ia_01_Jun.patch (subsumed by next one)
+jgrimm_tsn_lt_04_Jun.patch (subsumed by next one)
+EDITED: jgrimm_ecn_06_Jun.patch
+
+DONE: We still want to edit Jon's patch to deal with the ecn_allowed vs.
+ ecn_capable issue.
+
+Mon Jun 18 12:07:32 CDT 2001
+DONE: xingang_patch.debug.v011
+xingang_patch.INIT_ACK.v011
+
+Wed Jun 20 18:06:20 CDT 2001
+Fix Daisy's bug: Null pointer check needed for chunks
+
+sctp_make_chunk() may return a NULL pointer, therefore,
+every place that sctp_make_chunk() is called needs to
+verify the return value to prevent from using any NULL
+pointer down the road. Right now, in 2_4_1-0_1_1, all
+of these routines, such as sctp_make_init(),
+sctp_make_data_empty(), sctp_make_sack(), etc, uses the
+return value from sctp_make_chunk() assuming that it is
+non-NULL.
+
+Here are functions which are propigating the NULL bug:
+sctp_make_init
+
+Wed Aug 1 13:25:18 CDT 2001
+DONE: Apply Jon's patch
+DONE: Remove definitions of *Unified*
+DONE: Add comments on deviation from CWR rules.
+DONE: Make myNextTSN an atomic_t.
+DONE: Create sctp_config_packet(vTag, ecn_handler), and (*packet->config)()
+Move last_cwr_tsn adjustment into sctp_handle_congestion().
+Move CWR generation into the state function?
+
+Fri Aug 17 18:38:29 CDT 2001
+We're going through sctp_ipv6.0_1_2.patch. We've read everything but
+the tests.
+
+Mon Aug 20 15:37:47 CDT 2001
+We're about to plunge back into the ipv6 patch, mostly after the SCTP
+Business meeting at 4pm, hopefully after we commit the latest changes
+(the ones to the style guide and to sctp_v4_rcv().)
+
+Thu Aug 23 13:45:53 CDT 2001
+We cleared all outstanding integration (bug fixes, cmd_seq_t,
+ChunkDesc overallocation...). We also refactored the retval timers to
+be sctp_cmd_seq_t's. Now the trick is to get a test to fail because
+of the sctp_gen_sack() timer issue.
+
+Fri Aug 24 18:51:20 CDT 2001
+
+Well, we got the test (ft_frame_sack) to fail. Not quite where we
+wanted...but we have a pretty cool test to make up for it. Where we
+*do* fail is by sending one too many SACKs (for the test, Piggy). We
+send a SACK for every odd numbered packet without considering SACK
+timeouts. This is legal, but inelegant and screwy.
+
+On Monday, we're going to check and see how much torture this will be
+to refactor. Then we'll probably do it anyway, code-starved as we
+are.
+
+Mon Aug 27 18:04:01 CDT 2001
+OK, we are now passing ft_frame_sack, but ft_frame_ecn_basic fails.
+The problem is that we need to do ECN processing BEFORE we generate
+the SACK, but we are now generating the SACK in the side effects
+interpreter, which runs BEFORE the rest of all that stuff. The fix is
+to convert ECN processing to use retval->commands.
+
+Tue Aug 28 17:50:27 CDT 2001
+Notes on ft_frame_lostpackets (mysterious dup TSNs):
+??? Shouldn't we be sacking 98d?
+AAA No, because c and d are in the same packet
+??? How many times do we start the SACK timer per packet? Should this be
+conditional on end_of_packet?
+AAA I think once per packet, since we're running a small danger of ST
+expiration before all data is processed. Might as well wait. We do now.
+
+NNN In the non-sequential case, our sack doesn't gap ack (that's one),
+also, we sack on the reception of the middle data in that test, and
+then (presumably) stop the sack timer so the "forward time until sack"
+there does nothing.
+
+NNN When the rtx timer expires, we naturally deliver all 3 things in
+queue, and the middle one (a dup TSN) kills the test.
+
+So: a) we should gap ack, and b) dup TSNs shouldn't kill the test.
+
+SACK hunt:
+doTSNupdate looks ok.
+In sctp_gen_sack(), we would (I think) have sent f because it's an
+alternate data packet, but we also send it because it's a gap--
+(AP(max_tsn_seen) is above the AP(CTSNAckP)).
+AHA! sctp_make_sack() evades the whole topic of gap acking!
+That'll do it...
+
+Wed Aug 29 10:41:31 CDT 2001
+Upgraded ft_frame_lostpackets to see a gap-ack-unconditional sack.
+
+??? How can we fail the test when we don't gap ack without failing on
+dup TSNs?
+
+Wed Aug 29 15:15:29 CDT 2001
+We've now created a stub for duplicate reporting--a duplicate TSN is
+no longer an error.
+
+We're going to eliminate our duplicate detection test and see if we
+now could pass ft_frame_lostpackets... Yep! The new test is
+meaningful!
+
+Our new goal is to make the revised ft_frame_lostpackets pass by
+implementing gap acks. But first...
+
+Change to using Jon's new data structure!
+Integrate sctp_tsnmap_t.
+Implement gap acks.
+
+Wed Aug 29 16:34:55 CDT 2001
+We are going through lksctp-2_4_1-0_1_13.tsnmap.patch2 preparing
+comments and massaging the patch. We need to finish this and apply
+the patch.
+
+Thu Aug 30 18:00:54 CDT 2001
+We applied Jon's patches and refactored the TSN map code to use them.
+
+Tomorrow, Gap Acks!
+
+Fri Aug 31 14:44:37 CDT 2001
+DONE: Add a descriptive comment for sctp_check_transmitted().
+DONE: Remove the comment at sctp_outqueue.c:636.
+
+Fri Aug 31 15:59:34 CDT 2001
+OK, frametest and unit_test both pass completely.
+Unfortunately, we seem to have fixed ft_frame_biggap. Since we did
+NOT implement fast retran, we were not expecting this. We want this
+test to fail again.
+
+There are two possibilities:
+1) The test is wrong--it does not truely generate the big gap condition.
+2) We introduced a bug which masks the big gap bug.
+3) We really did fix the bug.
+
+It was possibility 3. Oops. We did not implement fast retran, but we
+DID make big gap a command rather than an error.
+
+Tue Sep 4 11:09:20 CDT 2001
+
+We successfully transferred 10M of data from the user space
+implementation to a live lksctp. Throughput was pretty raw--about
+25k/sec on a 100Mbit link with a PII-400, and 100 byte chunks. The
+fact that we do not advertise a growing rwnd hurts us a lot--we'd be
+about 1.8X faster if we did. That's still not extraordinarily
+fast--we really want to try this with the printk()s removed.
+
+Mon Sep 10 17:49:29 CDT 2001
+A little integration makes the world go round. (patch.inaddr_any.04)
+
diff --git a/libsctp.pc.in b/libsctp.pc.in
new file mode 100644
index 0000000..b1eafaf
--- /dev/null
+++ b/libsctp.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: sctp
+Description: User-level SCTP API library
+Version: @VERSION@
+Libs: -L${libdir} -lsctp
+Cflags: -I${includedir}
diff --git a/lksctp-tools.spec.in b/lksctp-tools.spec.in
new file mode 100644
index 0000000..8c2ce1b
--- /dev/null
+++ b/lksctp-tools.spec.in
@@ -0,0 +1,192 @@
+# -*- rpm-spec -*-
+#
+# lksctp-tools.spec.in --- RPM'ed lksctp-tools
+# Author : Francois-Xavier Kowalski
+# Created On : Sat Jan 10 14:53:53 2004
+# Last Modified By: Vlad Yasevich
+# Last Modified On: Tue Jan 08 10:56 EDT 2013
+#
+# (c) Copyright Hewlett-Packard Company 2004
+# (C) Copyright IBM Corp. 2004
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License v2 as published by the Free Software Foundation; only
+# version 2 of the License is valid for this software, unless
+# explicitly otherwise stated.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License v2 along with this program; if not, write to the
+# Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+# MA 02139, USA.
+
+%define lksctp_version @VERSION@
+
+# older lksctp-tools file name did not conform to RPM file naming
+# conventions
+
+%define pack_version %{lksctp_version}
+%define file_version %{lksctp_version}
+
+Summary: User-space access to Linux Kernel SCTP
+Name: @PACKAGE@
+Version: %{pack_version}
+Release: 1
+License: LGPL
+Group: System Environment/Libraries
+URL: http://lksctp.sourceforge.net
+Source0: %{name}-%{file_version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
+BuildRequires: gcc
+#BuildRequires: tetex, tetex-latex, tetex-xdvi, tetex-dvips
+#BuildRequires: ghostscript, enscript
+BuildRequires: libtool, automake, autoconf
+
+%description
+This is the lksctp-tools package for Linux Kernel SCTP Reference
+Implementation.
+
+This package is intended to supplement the Linux Kernel SCTP Reference
+Implementation now available in the Linux kernel source tree in
+versions 2.5.36 and following. For more information on LKSCTP see the
+package documentation README file, section titled "LKSCTP - Linux
+Kernel SCTP."
+
+This package contains the base run-time library & command-line tools.
+
+%package devel
+Summary: Development kit for lksctp-tools
+Group: Development/Libraries
+Requires: %{name} = %{version}
+Requires: glibc-devel
+
+%description devel
+Development kit for lksctp-tools
+
+- Man pages
+- Header files
+- Static libraries
+- Symlinks to dynamic libraries
+- Tutorial source code
+
+%package doc
+Summary: Documents pertaining to SCTP
+Group: System Environment/Libraries
+Requires: %{name} = %{version}
+
+%description doc
+Documents pertaining to LKSCTP & SCTP in general
+- IETF RFC's & Internet Drafts
+
+%prep
+%setup -q -n %{name}-%{file_version}
+
+%build
+%configure --enable-shared --enable-static
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR="$RPM_BUILD_ROOT"
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING ChangeLog COPYING.lib
+%{_bindir}/*
+%{_libdir}/libsctp.so.*
+%{_libdir}/@PACKAGE@/*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}
+%{_libdir}/libsctp.so
+%{_libdir}/libsctp.a
+%{_libdir}/libsctp.la
+%{_datadir}/@PACKAGE@/*
+%{_mandir}/*
+
+%files doc
+%defattr(-,root,root,-)
+%doc doc/*.txt
+
+%changelog
+* Mon May 09 2016 Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> 1.0.17-1
+- 1.0.17 Release
+
+* Tue Feb 18 2014 Daniel Borkmann <dborkman@redhat.com> 1.0.16-1
+- 1.0.16 Release
+
+* Sun May 12 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.15-1
+- 1.0.15 Release
+
+* Wed Apr 05 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.14-1
+- 1.0.14 Release
+
+* Wed Jan 23 2013 Daniel Borkmann <dborkman@redhat.com> 1.0.13-1
+- 1.0.13 Release
+
+* Tue Jan 08 2013 Vlad Yasevich <vyasevich@gmail.com> 1.0.12-1
+- 1.0.12 Release
+
+* Wed Oct 21 2009 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.11-1
+- 1.0.11 Release
+
+* Fri Mar 27 2009 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.10-1
+- 1.0.10 Release
+
+* Sun Jun 13 2008 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.9-1
+- 1.0.9 Release
+
+* Fri Feb 01 2008 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.8-1
+- 1.0.8 Release
+
+* Fri Jun 29 2007 Vlad Yasevich <vladislav.yasevich@hp.com> 1.0.7-1
+- 1.0.7 Release
+
+* Fri Feb 3 2006 Sridhar Samudrala <sri@us.ibm.com> 1.0.6-1
+- 1.0.6 Release
+
+* Tue Jan 3 2006 Sridhar Samudrala <sri@us.ibm.com> 1.0.5-1
+- 1.0.5 Release
+
+* Fri Oct 28 2005 Sridhar Samudrala <sri@us.ibm.com> 1.0.4-1
+- 1.0.4 Release
+
+* Thu Sep 1 2005 Sridhar Samudrala <sri@us.ibm.com> 1.0.3-1
+- 1.0.3 Release
+
+* Thu Dec 30 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.2-1
+- 1.0.2 Release
+
+* Tue May 11 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.1-1
+- 1.0.1 Release
+
+* Thu Feb 26 2004 Sridhar Samudrala <sri@us.ibm.com> 1.0.0-1
+- 1.0.0 Release
+
+* Fri Feb 6 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.9.0-1
+- package only .txt doc files
+
+* Wed Feb 4 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.7.5-1
+- badly placed & undelivered files
+- simplified delivery list
+
+* Tue Jan 27 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 0.7.5-1
+- Integrate comment from project team
+
+* Sat Jan 10 2004 Francois-Xavier Kowalski <francois-xavier.kowalski@hp.com> 2.6.0_test7_0.7.4-1
+- Creation
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..1ff72df
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,2 @@
+*.m4
+!sctp.m4
diff --git a/m4/sctp.m4 b/m4/sctp.m4
new file mode 100644
index 0000000..6593517
--- /dev/null
+++ b/m4/sctp.m4
@@ -0,0 +1,63 @@
+# Handy references:
+# https://www.gnu.org/software/autoconf/manual/autoconf.html#Generic-Structures
+# AC_CHECK_MEMBER (aggregate.member, [action-if-found], [action-if-not-found], [includes = 'AC_INCLUDES_DEFAULT'])
+# https://www.gnu.org/software/autoconf/manual/autoconf.html#Generic-Types
+# AC_CHECK_TYPE (type, [action-if-found], [action-if-not-found], [includes = 'AC_INCLUDES_DEFAULT'])
+
+# Macros to assist on probing kernel features
+# Probes if a type is defined
+AC_DEFUN([LKSCTP_CHECK_TYPE], [{
+AC_CHECK_TYPE([$1],
+ AC_DEFINE([$2], 1,
+ [Define if $1 is present.])
+ AM_CONDITIONAL([$2], [true]),
+ AM_CONDITIONAL([$2], [false]),
+ [AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
+
+# Probes if a struct has a given member
+AC_DEFUN([LKSCTP_CHECK_MEMBER], [{
+AC_CHECK_MEMBER([$1],
+ AC_DEFINE([$2], 1,
+ [Define if $1 is present.])
+ AM_CONDITIONAL([$2], [true]),
+ AM_CONDITIONAL([$2], [false]),
+ [AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
+
+# Probes if a declaration is present
+AC_DEFUN([LKSCTP_CHECK_DECL], [{
+AC_CHECK_DECL([$1],
+ AC_DEFINE([$2], 1,
+ [Define if $1 is present.])
+ AM_CONDITIONAL([$2], [true]),
+ AM_CONDITIONAL([$2], [false]),
+ [AC_INCLUDES_DEFAULT
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_LINUX_SCTP_H
+# include <linux/sctp.h>
+#endif
+])}])
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..eabfe6f
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,12 @@
+# -*- Makefile -*-
+#
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+man7_MANS = sctp.7
+
+man3_MANS = sctp_bindx.3 sctp_getladdrs.3 sctp_getpaddrs.3 sctp_opt_info.3 \
+ sctp_peeloff.3 sctp_recvmsg.3 sctp_sendmsg.3 sctp_connectx.3 \
+ sctp_send.3 sctp_sendv.3 sctp_recvv.3
+
+EXTRA_DIST += $(man3_MANS) $(man7_MANS)
diff --git a/man/sctp.7 b/man/sctp.7
new file mode 100644
index 0000000..2238a7f
--- /dev/null
+++ b/man/sctp.7
@@ -0,0 +1,352 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP 7 2005-10-25 "Linux Man Page" "Linux Programmer's Manual"
+.SH NAME
+sctp \- SCTP protocol.
+.SH SYNOPSIS
+.nf
+.B #include <sys/socket.h>
+.B #include <netinet/in.h>
+.B #include <netinet/sctp.h>
+.sp
+.B sctp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+.B sctp_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+.fi
+.SH DESCRIPTION
+This is an implementation of the SCTP protocol as defined in RFC2960 and
+RFC3309. It is a message oriented, reliable transport protocol with direct
+support for multihoming that runs on top of
+.BR ip (7),
+and supports both v4 and v6 versions.
+.PP
+Like TCP, SCTP provides reliable, connection oriented data delivery with
+congestion control. Unlike TCP, SCTP also provides message boundary
+preservation, ordered and unordered message delivery, multi-streaming and
+multi-homing. Detection of data corruption, loss of data and duplication of
+data is achieved by using checksums and sequence numbers. A selective
+retransmission mechanism is applied to correct loss or corruption of data.
+.PP
+This implementation supports a mapping of SCTP into sockets API as defined
+in the draft-ietf-tsvwg-sctpsocket-10.txt(Sockets API extensions for SCTP).
+Two styles of interfaces are supported.
+.PP
+A
+.B one-to-many
+style interface with 1 to MANY relationship between socket and associations
+where the outbound association setup is implicit. The syntax of a one-to-many
+style socket() call is
+.PP
+.B sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+.PP
+A typical server in this style uses the following socket calls in sequence
+to prepare an endpoint for servicing requests.
+.PP
+ 1. socket()
+ 2. bind()
+ 3. listen()
+ 4. recvmsg()
+ 5. sendmsg()
+ 6. close()
+.PP
+A typical client uses the following calls in sequence to setup an association
+with a server to request services.
+.PP
+ 1. socket()
+ 2. sendmsg()
+ 3. recvmsg()
+ 4. close()
+.PP
+A
+.B one-to-one style
+interface with a 1 to 1 relationship between socket and
+association which enables existing TCP applications to be ported to SCTP with
+very little effort. The syntax of a one-to-one style socket() call is
+.PP
+.B sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+.PP
+A typical server in one-to-one style uses the following
+system call sequence to prepare an SCTP endpoint for servicing requests:
+.PP
+ 1. socket()
+ 2. bind()
+ 3. listen()
+ 4. accept()
+.PP
+The accept() call blocks until a new association is set up. It returns with a
+new socket descriptor. The server then uses the new socket descriptor to
+communicate with the client, using recv() and send() calls to get requests and
+send back responses. Then it calls
+.PP
+ 5. close()
+.PP
+to terminate the association. A typical client uses the following system call
+sequence to setup an association with a server to request services:
+.PP
+ 1. socket()
+ 2. connect()
+.PP
+After returning from connect(), the client uses send() and recv() calls to
+send out requests and receive responses from the server. The client calls
+.PP
+ 3. close()
+.PP
+to terminate this association when done.
+.SH "ADDRESS FORMATS"
+SCTP is built on top of IP (see
+.BR ip (7)).
+The address formats defined by
+.BR ip (7)
+apply to SCTP. SCTP only supports point-to-point communication; broadcasting
+and multicasting are not supported.
+.SH SYSCTLS
+These variables can be accessed by the
+.B /proc/sys/net/sctp/*
+files or with the
+.BR sysctl (2)
+interface. In addition, most IP sysctls also apply to SCTP. See
+.BR ip (7).
+.TP
+Please check kernel documentation for this, at Documentation/networking/ip-sysctl.txt.
+.SH "STATISTICS"
+These variables can be accessed by the
+.B /proc/net/sctp/*
+files.
+.TP
+.B assocs
+Displays the following information about the active associations.
+assoc ptr, sock ptr, socket style, sock state, association state, hash bucket,
+association id, bytes in transmit queue, bytes in receive queue, user id,
+inode, local port, remote port, local addresses and remote addresses.
+.TP
+.B eps
+Displays the following information about the active endpoints.
+endpoint ptr, sock ptr, socket style, sock state, hash bucket, local port,
+user id, inode and local addresses.
+.TP
+.B snmp
+Displays the following statistics related to SCTP states, packets and chunks.
+.TP
+.TP
+.B SctpCurrEstab
+The number of associations for which the current state is either ESTABLISHED,
+SHUTDOWN-RECEIVED or SHUTDOWN-PENDING.
+.TP
+.B SctpActiveEstabs
+The number of times that associations have made a direct transition to the
+ESTABLISHED state from the COOKIE-ECHOED state. The upper layer initiated the
+association attempt.
+.TP
+.B SctpPassiveEstabs
+The number of times that associations have made a direct transition to the
+ESTABLISHED state from the CLOSED state. The remote endpoint initiated the
+association attempt.
+.TP
+.B SctpAborteds
+The number of times that associations have made a direct transition to the
+CLOSED state from any state using the primitive 'ABORT'. Ungraceful
+termination of the association.
+.TP
+.B SctpShutdowns
+The number of times that associations have made a direct transition to the
+CLOSED state from either the SHUTDOWN-SENT state or the SHUTDOWN-ACK-SENT
+state. Graceful termination of the association.
+.TP
+.B SctpOutOfBlues
+The number of out of the blue packets received by the host. An out of the blue
+packet is an SCTP packet correctly formed, including the proper checksum, but
+for which the receiver was unable to identify an appropriate association.
+.TP
+.B SctpChecksumErrors
+The number of SCTP packets received with an invalid checksum.
+.TP
+.B SctpOutCtrlChunks
+The number of SCTP control chunks sent (retransmissions are not included).
+Control chunks are those chunks different from DATA.
+.TP
+.B SctpOutOrderChunks
+The number of SCTP ordered data chunks sent (retransmissions are not included).
+.TP
+.B SctpOutUnorderChunks
+The number of SCTP unordered chunks(data chunks in which the U bit is set
+to 1) sent (retransmissions are not included).
+.TP
+.B SctpInCtrlChunks
+The number of SCTP control chunks received (no duplicate chunks included).
+.TP
+.B SctpInOrderChunks
+The number of SCTP ordered data chunks received (no duplicate chunks included).
+.TP
+.B SctpInUnorderChunks
+The number of SCTP unordered chunks(data chunks in which the U bit is set
+to 1) received (no duplicate chunks included).
+.TP
+.B SctpFragUsrMsgs
+The number of user messages that have to be fragmented because of the MTU.
+.TP
+.B SctpReasmUsrMsgs
+The number of user messages reassembled, after conversion into DATA chunks.
+.TP
+.B SctpOutSCTPPacks
+The number of SCTP packets sent. Retransmitted DATA chunks are included.
+.TP
+.B SctpInSCTPPacks
+The number of SCTP packets received. Duplicates are included.
+.SH "SOCKET OPTIONS"
+To set or get a SCTP socket option, call
+.BR getsockopt (2)
+to read or
+.BR setsockopt (2)
+to write the option with the option level argument set to
+.BR SOL_SCTP.
+.TP
+.BR SCTP_RTOINFO.
+This option is used to get or set the protocol parameters used to
+initialize and bound retransmission timout(RTO). The structure sctp_rtoinfo
+defined in /usr/include/netinet/sctp.h is used to access and modify these
+parameters.
+.TP
+.B SCTP_ASSOCINFO
+This option is used to both examine and set various association and endpoint
+parameters. The sturcture sctp_assocparams defined in
+/usr/include/netinet/sctp.h is used to access and modify these parameters.
+.TP
+.B SCTP_INITMSG
+This option is used to get or set the protocol parameters for the default
+association initialization. The structure sctp_initmsg defined in
+/usr/include/netinet/sctp.h is used to access and modify these parameters.
+
+Setting initialization parameters is effective only on an unconnected
+socket (for one-to-many style sockets only future associations are
+effected by the change). With one-to-one style sockets, this option
+is inherited by sockets derived from a listener socket.
+.TP
+.B SCTP_NODELAY
+Turn on/off any Nagle-like algorithm. This means that packets are generally
+sent as soon as possible and no unnecessary delays are introduced, at the cost
+of more packets in the network. Expects an integer boolean flag.
+.TP
+.B SCTP_AUTOCLOSE
+This socket option is applicable to the one-to-many style socket
+only. When set it will cause associations that are idle for more than
+the specified number of seconds to automatically close. An
+association being idle is defined an association that has NOT sent or
+received user data. The special value of 0 indicates that no
+automatic close of any associations should be performed. The option
+expects an integer defining the number of seconds of idle time before
+an association is closed.
+.TP
+.B SCTP_SET_PEER_PRIMARY_ADDR
+Requests that the peer mark the enclosed address as the association
+primary. The enclosed address must be one of the association's
+locally bound addresses. The structure sctp_setpeerprim defined in
+/usr/include/netinet/sctp.h is used to make a set peer primary request.
+.TP
+.B SCTP_PRIMARY_ADDR
+Requests that the local SCTP stack use the enclosed peer address as
+the association primary. The enclosed address must be one of the
+association peer's addresses. The structure sctp_prim defined in
+/usr/include/netinet/sctp.h is used to make a get/set primary request.
+.TP
+.B SCTP_DISABLE_FRAGMENTS
+This option is a on/off flag and is passed an integer where a non-zero is on
+and a zero is off. If enabled no SCTP message fragmentation will be performed.
+Instead if a message being sent exceeds the current PMTU size, the message will
+NOT be sent and an error will be indicated to the user.
+.TP
+.B SCTP_PEER_ADDR_PARAMS
+Using this option, applications can enable or disable heartbeats for any peer
+address of an association, modify an address's heartbeat interval, force a
+heartbeat to be sent immediately, and adjust the address's maximum number of
+retransmissions sent before an address is considered unreachable. The structure
+sctp_paddrparams defined in /usr/include/netinet/sctp.h is used to
+access and modify an address's parameters.
+.TP
+.B SCTP_DEFAULT_SEND_PARAM
+Applications that wish to use the sendto() system call may wish to specify
+a default set of parameters that would normally be supplied through the
+inclusion of ancillary data. This socket option allows such an application to
+set the default sctp_sndrcvinfo structure. The application that wishes to use
+this socket option simply passes in to this call the sctp_sndrcvinfo structure
+defined in /usr/include/netinet/sctp.h. The input parameters accepted by this
+call include sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context,
+sinfo_timetolive. The user must set the sinfo_assoc_id field to identify the
+ association to affect if the caller is using the one-to-many style.
+.TP
+.B SCTP_EVENTS
+This socket option is used to specify various notifications and ancillary data
+the user wishes to receive. The structure sctp_event_subscribe defined in
+/usr/include/netinet/sctp.h is used to access or modify the events of interest
+to the user.
+.TP
+.B SCTP_I_WANT_MAPPED_V4_ADDR
+This socket option is a boolean flag which turns on or off mapped V4
+addresses. If this option is turned on and the socket is type PF_INET6,
+then IPv4 addresses will be mapped to V6 representation. If this option is
+turned off, then no mapping will be done of V4 addresses and a user will
+receive both PF_INET6 and PF_INET type addresses on the socket.
+
+By default this option is turned on and expects an integer to be passed where
+non-zero turns on the option and zero turns off the option.
+.TP
+.B SCTP_MAXSEG
+This socket option specifies the maximum size to put in any outgoing
+SCTP DATA chunk. If a message is larger than this size it will be
+fragmented by SCTP into the specified size. Note that the underlying
+SCTP implementation may fragment into smaller sized chunks when the
+PMTU of the underlying association is smaller than the value set by
+the user. The option expects an integer.
+
+The default value for this option is 0 which indicates the user is
+NOT limiting fragmentation and only the PMTU will effect SCTP's
+choice of DATA chunk size.
+.TP
+.B SCTP_STATUS
+Applications can retrieve current status information about an association,
+including association state, peer receiver window size, number of unacked
+data chunks, and number of data chunks pending receipt. This information is
+read-only. The structure sctp_status defined in /usr/include/netinet/sctp.h
+is used to access this information.
+.TP
+.B SCTP_GET_PEER_ADDR_INFO
+Applications can retrieve information about a specific peer address
+of an association, including its reachability state, congestion window,
+and retransmission timer values. This information is read-only. The structure
+sctp_paddr_info defined in /usr/include/netinet/sctp.h is used to access this
+information.
+.TP
+.B SCTP_GET_ASSOC_STATS
+Applications can retrieve current statistics about an association, including
+SACKs sent and received, SCTP packets sent and received. The complete list can
+be found in /usr/include/netinet/sctp.h in struct sctp_assoc_stats.
+.SH AUTHORS
+Sridhar Samudrala <sri@us.ibm.com>
+.SH "SEE ALSO"
+.BR socket (7),
+.BR socket (2),
+.BR ip (7),
+.BR bind (2),
+.BR listen (2),
+.BR accept (2),
+.BR connect (2),
+.BR sendmsg (2),
+.BR recvmsg (2),
+.BR sysctl (2),
+.BR getsockopt (2),
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getladdrs (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_opt_info (3).
+.sp
+RFC2960, RFC3309 for the SCTP specification.
diff --git a/man/sctp_bindx.3 b/man/sctp_bindx.3
new file mode 100644
index 0000000..e1b151b
--- /dev/null
+++ b/man/sctp_bindx.3
@@ -0,0 +1,94 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_BINDX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_bindx \- Add or remove bind addresses on a socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_bindx(int " sd ", struct sockaddr * " addrs ", int " addrcnt ,
+.BI " int " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_bindx
+adds or removes a set of bind addresses passed in the array
+.I addrs
+to/from the socket
+.I sd.
+.I addrcnt
+is the number of addresses in the array and the
+.I flags
+paramater indicates if the addresses need to be added or removed.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses passed must be IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses passed can be either IPv4 or IPv6
+addresses.
+.PP
+.I addrs
+is a pointer to an array of one or more socket addresses. Each address is
+contained in its appropriate structure(i.e. struct sockaddr_in or struct
+sockaddr_in6). The family of the address type must be used to distinguish
+the address length. The caller specifies the number of addresses in the
+array with
+.I addrcnt.
+.PP
+The
+.I flags
+parameter can be either
+.B SCTP_BINDX_ADD_ADDR
+or
+.B SCTP_BINDX_REM_ADDR.
+An application can use
+.B SCTP_BINDX_ADD_ADDR
+to associate additional addresses with an endpoint after calling
+.BR bind(2).
+.B SCTP_BINDX_REM_ADDR
+directs SCTP to remove the given addresses from the association.
+A caller may not remove all addresses from an association. It will
+fail with
+.B EINVAL.
+.SH "RETURN VALUE"
+On success, 0 is returned. On failure, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B ENOTSOCK
+.I sd
+is a descriptor for a file, not a socket.
+.TP
+.B EFAULT
+Error while copying in or out from the user address space.
+.TP
+.B EINVAL
+Invalid port or address or trying to remove all addresses from an association.
+.TP
+.B EACCES
+The address is protected, and the user is not the super-user.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
+.BR sctp_connectx (3)
diff --git a/man/sctp_connectx.3 b/man/sctp_connectx.3
new file mode 100644
index 0000000..c75454c
--- /dev/null
+++ b/man/sctp_connectx.3
@@ -0,0 +1,144 @@
+.\" (C) Copyright Frank Filz IBM Corp. 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_CONNECTX 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_connectx \- initiate a connection on an SCTP socket using multiple
+destination addresses.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_connectx(int " sd ", struct sockaddr * " addrs ", int " addrcnt,
+.BI " sctp_assoc_t * "id );
+.fi
+.SH DESCRIPTION
+.BR sctp_connectx
+initiates a connection to a set of addresses passed in the array
+.I addrs
+to/from the socket
+.I sd.
+.I addrcnt
+is the number of addresses in the array.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses passed must be IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses passed can be either IPv4 or IPv6
+addresses.
+.PP
+.I addrs
+is a pointer to an array of one or more socket addresses. Each address is
+contained in its appropriate structure(i.e. struct sockaddr_in or struct
+sockaddr_in6). The family of the address type must be used to distinguish
+the address length. The caller specifies the number of addresses in the
+array with
+.I addrcnt.
+.PP
+.I id
+is a pointer to the association id and, if provided, will be set to the
+identifier of the newly created association.
+.SH "RETURN VALUE"
+On success, 0 is returned. On failure, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B ENOTSOCK
+.I sd
+is a descriptor for a file, not a socket.
+.TP
+.B EFAULT
+Error while copying in or out from the user address space.
+.TP
+.B EINVAL
+Invalid port or address.
+.TP
+.B EACCES
+The address is protected, and the user is not the super-user.
+.TP
+.B EISCONN
+The socket is already connected.
+.TP
+.B ECONNREFUSED
+No one listening on the remote address.
+.TP
+.B ETIMEDOUT
+Timeout while attempting connection. The server may be too
+busy to accept new connections. Note that for IP sockets the timeout may
+be very long when syncookies are enabled on the server.
+.TP
+.B ENETUNREACH
+Network is unreachable.
+.TP
+.B EADDRINUSE
+Local address is already in use.
+.TP
+.B EINPROGRESS
+The socket is non-blocking and the connection cannot be completed
+immediately. It is possible to
+.BR select (2)
+or
+.BR poll (2)
+for completion by selecting the socket for writing. After
+.B select
+indicates writability, use
+.BR getsockopt (2)
+to read the
+.B SO_ERROR
+option at level
+.B SOL_SOCKET
+to determine whether
+.B connect
+completed successfully
+.RB ( SO_ERROR
+is zero) or unsuccessfully
+.RB ( SO_ERROR
+is one of the usual error codes listed here,
+explaining the reason for the failure).
+.TP
+.B EALREADY
+The socket is non-blocking and a previous connection attempt has not yet
+been completed.
+.TP
+.B EAGAIN
+No more free local ports or insufficient entries in the routing cache. For
+.B PF_INET
+see the
+.B net.ipv4.ip_local_port_range
+sysctl in
+.BR ip (7)
+on how to increase the number of local ports.
+.TP
+.B EAFNOSUPPORT
+The passed address didn't have the correct address family in its
+.I sa_family
+field.
+.TP
+.B EACCES, EPERM
+The user tried to connect to a broadcast address without having the socket
+broadcast flag enabled or the connection request failed because of a local
+firewall rule.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_getladdrs.3 b/man/sctp_getladdrs.3
new file mode 100644
index 0000000..c5aad14
--- /dev/null
+++ b/man/sctp_getladdrs.3
@@ -0,0 +1,78 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_GETLADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_getladdrs \- Returns all locally bound addresses on a socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_getladdrs(int " sd ", sctp_assoc_t " assoc_id ,
+.BI " struct sockaddr **" addrs );
+.sp
+.BI "void sctp_freeladdrs(struct sockaddr *" addrs );
+.fi
+.SH DESCRIPTION
+.BR sctp_getladdrs
+returns all locally bound addresses on a socket. On return,
+.I addrs
+will point to a dynamically allocated packed array of
+.B sockaddr
+structures of the appropriate type for each local address. The caller
+should use
+.BR sctp_freeladdrs
+to free the memory. Note that the in/out parameter
+.I addrs
+must not be NULL.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses returned will be all IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6
+addresses.
+.PP
+For one-to-many style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.PP
+If the
+.I id
+field is set to 0, then the locally bound addresses are returned
+without regard to any particular association.
+.PP
+.BR sctp_freeladdrs
+frees all the resources allocated by
+.BR sctp_getladdrs
+.SH "RETURN VALUE"
+On success,
+.BR sctp_getladdrs
+returns the number of local addresses bound to the socket. If the socket
+is unbound, 0 is returned and the value of
+.I *addrs
+is undefined. On error,
+.BR sctp_getladdrs
+returns -1 and the value of
+.I *addrs
+is undefined.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_getpaddrs.3 b/man/sctp_getpaddrs.3
new file mode 100644
index 0000000..9167dfc
--- /dev/null
+++ b/man/sctp_getpaddrs.3
@@ -0,0 +1,72 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_GETPADDRS 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_getpaddrs \- Returns all peer addresses in an association.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_getpaddrs(int " sd ", sctp_assoc_t " assoc_id ,
+.BI " struct sockaddr **" addrs );
+.sp
+.BI "void sctp_freepaddrs(struct sockaddr *" addrs );
+.fi
+.SH DESCRIPTION
+.BR sctp_getpaddrs
+returns all peer addresses in an association. On return,
+.I addrs
+will point to a dynamically allocated packed array of
+.B sockaddr
+structures of the appropriate type for each address. The caller should use
+.BR sctp_freepaddrs
+to free the memory. Note that the in/out parameter
+.I addrs
+must not be NULL.
+.PP
+If
+.I sd
+is an IPv4 socket, the addresses returned will be all IPv4 addresses. If
+.I sd
+is an IPv6 socket, the addresses returned can be a mix of IPv4 or IPv6
+addresses.
+.PP
+For one-to-many style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.PP
+.BR sctp_freepaddrs
+frees all the resources allocated by
+.BR sctp_getpaddrs.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_getpaddrs
+returns the number of peer addresses in the association. If there is no
+association on this socket, 0 is returned and the value of
+.I *addrs
+is undefined. On error,
+.BR sctp_getpaddrs
+returns -1 and the value of
+.I *addrs
+is undefined.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_opt_info.3 b/man/sctp_opt_info.3
new file mode 100644
index 0000000..9d63c9c
--- /dev/null
+++ b/man/sctp_opt_info.3
@@ -0,0 +1,56 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_OPT_INFO 3 2004-01-30 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_optinfo \- Get options on a SCTP socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_opt_info(int " sd ", sctp_assoc_t " id ", int " opt ,
+.BI " void * " arg ", socklen_t * " size);
+.fi
+.SH DESCRIPTION
+.BR sctp_opt_info
+is a wrapper library function that can be used to get SCTP level options on
+a socket.
+.I sd
+is the socket descriptor for which the option is requested. For one-to-many
+style sockets,
+.I id
+specifies the association to query. For one-to-one style sockets,
+.I id
+is ignored.
+.I opt
+specifes the SCTP socket option to get.
+.I arg
+is an option-specific structure buffer provided by the caller.
+.I size
+is a value-result parameter, initially containing the size of the buffer
+pointed to by
+.I arg
+and modifed on return to indicate the actual size of the value returned.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_opt_info
+returns 0 and on failure -1 is returned with errno set to the appropriate
+error code.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
diff --git a/man/sctp_peeloff.3 b/man/sctp_peeloff.3
new file mode 100644
index 0000000..7e66317
--- /dev/null
+++ b/man/sctp_peeloff.3
@@ -0,0 +1,74 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_PEELOFF 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_peeloff \- Branch off an association into a separate socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_peeloff(int " sd ", sctp_assoc_t " assoc_id );
+.BI "int sctp_peeloff_flags(int " sd ", sctp_assoc_t " assoc_id ", unsigned " flags );
+.fi
+.SH DESCRIPTION
+.B sctp_peeloff
+branches off an existing association
+.I assoc_id
+on a one-to-many style socket
+.I sd
+into a separate socket. The new socket is a one-to-one style socket.
+.PP
+This is particularly desirable when, for instance, the application wishes to
+have a number of sporadic message senders/receivers remain under the original
+one-to-many style socket, but branch off those assocations carrying high volume
+data traffic into their own separate socket descriptors.
+
+.B sctp_peeloff_flags
+is a variant of sctp_peeloff, in which flags describing the behavior of
+the newly peeled off socket can be specified. Currently the supported flags
+are:
+.TP
+.B SOCK_NONBLOCK
+Specifies that the new socket should not block on io operations.
+.TP
+.B SOCK_CLOEXEC
+Specifies that the new socket should be closed when the owning process calls
+exec.
+.SH "RETURN VALUE"
+On success, the new socket descriptor representing the branched-off asociation is returned.
+On error, \-1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.B EBADF
+.I sd
+is not a valid descriptor.
+.TP
+.B EINVAL
+The assoc id passed is invalid or if the socket is a one-to-one style socket.
+.TP
+.B ENOTSOCK
+Argument is a descriptor for a file, not a socket.
+.SH NOTES
+.TP
+sctp_peeloff_flags is a linux specific variant of sctp_peeloff. While it will compile on other systems, its use will result in an error return. Portable code should use sctp_peeloff.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_recvmsg.3 b/man/sctp_recvmsg.3
new file mode 100644
index 0000000..7854aec
--- /dev/null
+++ b/man/sctp_recvmsg.3
@@ -0,0 +1,71 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_RECVMSG 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_recvmsg \- Receive a message from a SCTP socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_recvmsg(int " sd ", void * " msg ", size_t " len ,
+.BI " struct sockaddr * " from ", socklen_t * " fromlen ,
+.BI " struct sctp_sndrcvinfo * " sinfo ", int * " msg_flags);
+.fi
+.SH DESCRIPTION
+.BR sctp_recvmsg
+is a wrapper library function that can be used to receive a message from
+a socket while using the advanced features of SCTP.
+.I sd
+is the socket descriptor on which the message pointed to by
+.I msg
+of length
+.I len
+is received.
+.PP
+If
+.I from
+is not NULL, the source address of the message is filled in. The argument
+.I fromlen
+is a value-result parameter. initialized to the size of the buffer associated
+with
+.I from ,
+and modified on return to indicate the actual size of the address stored.
+.PP
+.I sinfo
+is a pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the
+message.
+.I msg_flags
+is a pointer to a integer that is filled with any message flags like
+.B MSG_NOTIFICATION or
+.B MSG_EOR.
+The value of
+.I msg_flags
+pointer should be initialized to 0 to avoid unexpected behavior;
+.I msg_flags
+is also used as an input
+.I flags
+argument to
+.I recvmsg
+function.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_recvmsg
+returns the number of bytes received or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3)
diff --git a/man/sctp_recvv.3 b/man/sctp_recvv.3
new file mode 100644
index 0000000..a41cb33
--- /dev/null
+++ b/man/sctp_recvv.3
@@ -0,0 +1,99 @@
+.\" (C) Copyright Xin Long REDHAT Corp. 2018.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_RECVV 3 2018-04-29 "Linux 4.16 "Linux Programmer's Manual"
+.SH NAME
+sctp_recvv \- Receive a message from a SCTP socket with an extensible way.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_recvv(int " sd ", const struct iovec * " iov ", int " iovlen ,
+.BI " struct sockaddr * " from ", socklen_t * " fromlen ", void * " info ,
+.BI " socklen_t * " infolen ", unsigned int * " infotype ", int * " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_recvv
+provides an extensible way for the SCTP stack to pass up different SCTP
+attributes associated with a received message to an application.
+There are two types of attributes that can be returned by this call: the
+attribute of the received message and the attribute of the next message
+in the receive buffer. The caller enables the SCTP_RECVRCVINFO and
+SCTP_RECVNXTINFO socket options, respectively, to receive these attributes.
+Attributes of the received message are returned in struct sctp_rcvinfo,
+and attributes of the next message are returned in struct sctp_nxtinfo.
+If both options are enabled, both attributes are returned using the
+following structure.
+
+ struct sctp_recvv_rn {
+ struct sctp_rcvinfo recvv_rcvinfo;
+ struct sctp_nxtinfo recvv_nxtinfo;
+ };
+
+.I sd
+is the socket descriptor.
+.I iov
+is the scatter buffer, and only one user message is returned in this buffer.
+.I iovlen
+is the number of elements in iov.
+.I from
+is a pointer to a buffer to be filled with the sender of the received message's
+address.
+.I fromlen
+is an in/out parameter describing the from length.
+.I info
+is a pointer to the buffer to hold the attributes of the received message, the
+structure type of info is determined by the info_type parameter.
+.I infolen
+is an in/out parameter describing the size of the info buffer.
+On return,
+.I infotype
+is set to the type of the info buffer, and the current defined
+values are as follows:
+.TP
+.B SCTP_RECVV_NOINFO
+If neither SCTP_RECVRCVINFO nor SCTP_RECVNXTINFO options are enabled, no
+attribute will be returned. If only the SCTP_RECVNXTINFO option is enabled
+but there is no next message in the buffer, no attribute will be returned.
+In these cases, *info_type will be set to SCTP_RECVV_NOINFO.
+.TP
+.B SCTP_RECVV_RCVINFO
+The type of info is struct sctp_rcvinfo, and the attribute relates to the
+received message.
+.TP
+.B SCTP_RECVV_NXTINFO
+The type of info is struct sctp_nxtinfo, and the attribute relates to the
+next message in the receive buffer. This is the case when only the
+SCTP_RECVNXTINFO option is enabled and there is a next message in the buffer.
+.TP
+.B SCTP_RECVV_RN
+The type of info is struct sctp_recvv_rn. The recvv_rcvinfo field is the
+attribute of the received message, and the recvv_nxtinfo field is the attribute
+of the next message in the buffer. This is the case when both SCTP_RECVRCVINFO
+and SCTP_RECVNXTINFO options are enabled and there is a next message in the
+receive buffer.
+.PP
+.I flags
+is pointer to an integer to be filled with any message flags (e.g.,
+MSG_NOTIFICATION).
+.SH "RETURN VALUE"
+On success,
+.BR sctp_recvv
+returns the number of bytes received or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3)
diff --git a/man/sctp_send.3 b/man/sctp_send.3
new file mode 100644
index 0000000..ba66ecd
--- /dev/null
+++ b/man/sctp_send.3
@@ -0,0 +1,50 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SEND 3 2005-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_send \- Send a message from a SCTP socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_send(int " sd ", const void * " msg ", size_t " len ,
+.BI " const struct sctp_sndrcvinfo *" sinfo ",
+.BI " uint32_t " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_send
+is a wrapper library function that can be used to send a message from a socket
+without the use of the CMSG header structures.
+.I sd
+is the socket descriptor from which the message pointed to by
+.I msg
+of length
+.I len
+is sent.
+.I sinfo
+is a pointer to a sctp_sndrcvinfo structure.
+.I flags
+parameter is composed of a bitwise OR of the flags that can be be passed as
+the 3rd argument of a standard sendmsg() call.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendmsg
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
+.BR sctp_sendmsg (3),
+.BR sctp_sendv (3)
diff --git a/man/sctp_sendmsg.3 b/man/sctp_sendmsg.3
new file mode 100644
index 0000000..51828fb
--- /dev/null
+++ b/man/sctp_sendmsg.3
@@ -0,0 +1,86 @@
+.\" (C) Copyright Sridhar Samudrala IBM Corp. 2004, 2005.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SENDMSG 3 2004-10-25 "Linux 2.6" "Linux Programmer's Manual"
+.SH NAME
+sctp_sendmsg \- Send a message from a SCTP socket.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_sendmsg(int " sd ", const void * " msg ", size_t " len ,
+.BI " struct sockaddr *" to ", socklen_t " tolen ,
+.BI " uint32_t " ppid ", uint32_t " flags ,
+.BI " uint16_t " stream_no ", uint32_t " timetolive ,
+.BI " uint32_t " context );
+.fi
+.SH DESCRIPTION
+.BR sctp_sendmsg
+is a wrapper library function that can be used to send a message from a socket
+while using the advanced features of SCTP.
+.I sd
+is the socket descriptor from which the message pointed to by
+.I msg
+of length
+.I len
+is sent.
+.I to
+is the destination address of the message and
+.I tolen
+is the length of the destination address.
+.I stream_no
+identifies the stream number that the application wishes to send this message to.
+.I flags
+parameter is composed of a bitwise OR of the following values.
+.TP
+.B SCTP_UNORDERED
+This flags requests the un-ordered delivery of the message.
+.TP
+.B SCTP_ADDR_OVER
+This flag, in the one-to-many style, requests the SCTP stack to override the
+primary destination address with address specified in
+.I to.
+.TP
+.B SCTP_ABORT
+Setting this flag causes the specified association to abort by sending an ABORT
+message to the peer(one-to-many style only). The ABORT chunk will contain an
+error cause 'User Initiated Abort' with cause code 12. The cause specific
+information of this error cause is provided in
+.I msg.
+.TP
+.B SCTP_EOF
+Setting this flag invokes the SCTP graceful shutdown procedure on the specific
+association(one-to-many style only).
+.PP
+.I timetolive
+specifies the time duration in milliseconds. The sending side will expire the
+message if the message has not been sent to the peer within this time period.
+A value of 0 indicates that no timeout should occur on this message.
+.I ppid
+is an opaque unsigned value that is passed to the remote end along with the
+message.
+.I context
+is a 32 bit opaque value that is passed back to the upper layer along with the
+undelivered message if an error occurs on the send of the message.
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendmsg
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_sendv (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/man/sctp_sendv.3 b/man/sctp_sendv.3
new file mode 100644
index 0000000..03a2e44
--- /dev/null
+++ b/man/sctp_sendv.3
@@ -0,0 +1,97 @@
+.\" (C) Copyright Xin Long REDHAT Corp. 2018.
+.\"
+.\" Permission is granted to distribute possibly modified copies
+.\" of this manual provided the header is included verbatim,
+.\" and in case of nontrivial modification author and date
+.\" of the modification is added to the header.
+.\"
+.TH SCTP_SENDV 3 2018-04-29 "Linux 4.16 "Linux Programmer's Manual"
+.SH NAME
+sctp_sendv \- Send messages from a SCTP socket with an extensible way.
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/socket.h>
+.B #include <netinet/sctp.h>
+.sp
+.BI "int sctp_sendv(int " sd ", const struct iovec * " iov ", int " iovcnt ,
+.BI " struct sockaddr *" addrs ", int " addrcnt ", void * " info ,
+.BI " socklen_t " infolen ", unsigned int " infotype ", int " flags );
+.fi
+.SH DESCRIPTION
+.BR sctp_sendv
+provides an extensible way for an application to communicate different send
+attributes to the SCTP stack when sending a message. There are three types
+of attributes that can be used to describe a message to be sent. They are
+struct sctp_sndinfo, struct sctp_prinfo, and struct sctp_authinfo. The
+following structure, sctp_sendv_spa, is defined to be used when more than
+one of the above attributes are needed to describe a message to be sent.
+
+ struct sctp_sendv_spa {
+ uint32_t sendv_flags;
+ struct sctp_sndinfo sendv_sndinfo;
+ struct sctp_prinfo sendv_prinfo;
+ struct sctp_authinfo sendv_authinfo;
+ };
+
+The sendv_flags field holds a bitwise OR of SCTP_SEND_SNDINFO_VALID,
+SCTP_SEND_PRINFO_VALID, and SCTP_SEND_AUTHINFO_VALID indicating if
+the sendv_sndinfo/sendv_prinfo/sendv_authinfo fields contain valid
+information.
+
+.I sd
+is the socket descriptor.
+.I iov
+is the gather buffer, the data in the buffer is treated as a single
+user message.
+.I iovcnt
+is the number of elements in iov.
+.I addrs
+is an array of addresses to be used to set up an association or
+a single address to be used to send the message, and NULL is passed
+in if the caller neither wants to set up an association nor wants
+to send the message to a specific address.
+.I addrcnt
+is the number of addresses in the addrs array.
+.I info
+is a pointer to the buffer containing the attribute associated with the
+message to be sent, and the type is indicated by the info_type parameter.
+.I infolen
+is the length of info, in bytes.
+.I infotype
+identifies the type of the information provided in info ,and the current
+defined values are as follows:
+.TP
+.B SCTP_SENDV_NOINFO
+No information is provided. The parameter info is a NULL pointer, and
+infolen is 0.
+.TP
+.B SCTP_SENDV_SNDINFO
+The parameter info is pointing to a struct sctp_sndinfo.
+.TP
+.B SCTP_SENDV_PRINFO
+The parameter info is pointing to a struct sctp_prinfo.
+.TP
+.B SCTP_SENDV_AUTHINFO
+The parameter info is pointing to a struct sctp_authinfo.
+.TP
+.B SCTP_SENDV_SPA
+The parameter info is pointing to a struct sctp_sendv_spa.
+.PP
+.I flags
+The same flags as used by the sendmsg() call flags (e.g., MSG_DONTROUTE).
+.SH "RETURN VALUE"
+On success,
+.BR sctp_sendv
+returns the number of bytes sent or -1 if an error occurred.
+.SH "SEE ALSO"
+.BR sctp (7)
+.BR sctp_bindx (3),
+.BR sctp_connectx (3),
+.BR sctp_send (3),
+.BR sctp_recvmsg (3),
+.BR sctp_recvv (3),
+.BR sctp_peeloff (3),
+.BR sctp_getpaddrs (3),
+.BR sctp_getladdrs (3),
+.BR sctp_opt_info (3),
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c5b8fa6
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+SUBDIRS = apps include lib testlib withsctp
+
+if BUILD_TESTS
+SUBDIRS += func_tests
+endif
diff --git a/src/apps/.gitignore b/src/apps/.gitignore
new file mode 100644
index 0000000..a7ba019
--- /dev/null
+++ b/src/apps/.gitignore
@@ -0,0 +1,10 @@
+bindx_test
+myftp
+nagle_rcv
+nagle_snd
+peel_client
+peel_server
+sctp_darn
+sctp_status
+sctp_test
+sctp_xconnect
diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
new file mode 100644
index 0000000..7e32306
--- /dev/null
+++ b/src/apps/Makefile.am
@@ -0,0 +1,42 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I. -I$(top_builddir)/src/include -I$(top_srcdir)/src/testlib \
+ -g -O2 -fno-strict-aliasing -Wall -Wstrict-prototypes \
+ -Wimplicit-function-declaration
+
+AM_LDFLAGS =
+
+LDADD = $(top_builddir)/src/testlib/libsctputil.la \
+ $(top_builddir)/src/lib/libsctp.la
+
+# programs to be installed with the distriubution
+bin_PROGRAMS = sctp_darn sctp_test sctp_status
+
+# Test programs and libraries to build
+noinst_PROGRAMS = bindx_test nagle_snd nagle_rcv myftp sctp_xconnect \
+ peel_server peel_client sctp_test sctp_status
+
+$(top_builddir)/src/lib/libsctp.la:
+ $(MAKE) -C $(top_builddir)/src/lib libsctp.la
+
+$(top_builddir)/src/testlib/libsctputil.la:
+ $(MAKE) -C $(top_builddir)/src/testlib libsctputil.la
+
+# Specifying the sources
+bindx_test_SOURCES = bindx_test.c
+sctp_darn_SOURCES = sctp_darn.c sctp_darn.h
+sctp_test_SOURCES = sctp_test.c
+sctp_status_SOURCES = sctp_status.c
+nagle_rcv_SOURCES = nagle_rcv.c
+nagle_snd_SOURCES = nagle_snd.c
+myftp_SOURCES = myftp.c
+sctp_xconnect_SOURCES = sctp_xconnect.c
+peel_server_SOURCES = peel_server.c
+peel_client_SOURCES = peel_client.c
+
+# Tutorials
+pkgdoc_DATA = sctp_darn.c sctp_darn.h sctp_test.c sctp_status.c
diff --git a/src/apps/bindx_test.c b/src/apps/bindx_test.c
new file mode 100644
index 0000000..ff3de86
--- /dev/null
+++ b/src/apps/bindx_test.c
@@ -0,0 +1,134 @@
+ /* -*-c-*-
+ **
+ ** sctp-tools: Another bindx test.
+ **
+ ** $Id: bindx_test.c,v 1.1.1.1 2002/08/06 22:31:05 inaky Exp $
+ **
+ ** Distributed under the terms of the GPL v2.0 as described in
+ ** $top_srcdir/COPYING.
+ **
+ ** (C) Copyright IBM Corp. 2003
+ ** (C) 2002 Intel Corporation
+ ** Iñaky Pérez-González <inaky.perez-gonzalez@intel.com>:
+ ** Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#define _GNU_SOURCE /* GNU extensions */
+
+#include <stdlib.h> /* malloc() */
+#include <arpa/inet.h> /* inet_pton() */
+#include <errno.h>
+#include <sys/socket.h> /* socket() */
+#include <stdio.h> /* fprintf */
+#include <netinet/in.h> /* sockaddr_in */
+#include <unistd.h> /* close() */
+#include <string.h> /* strchr() */
+#include <netinet/sctp.h> /* bindx() */
+
+ /* Global stuff */
+
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+ /*! Main function: initialize, setup, run the main loop
+ **
+ **
+ */
+
+int main (int argc, char **argv)
+{
+ void *addr_buf, *buf_ptr;
+ void *addr_buf_size = 0;
+ size_t addrs, cnt;
+ int sd, result, port;
+ int domain = PF_INET6;
+
+ if (argc < 3) {
+ fprintf(stderr,
+ "Usage: bindx_test PORT IPADDR1 [IPADDR2 [...]]\n");
+ return 1;
+ }
+
+ port = atoi(argv[1]);
+ printf("bindx_test: INFO: Port is %d\n", port);
+
+ /* Allocate the maximum space for the specified no. of addresses.
+ * Assume all of them are v6 addresses.
+ */
+ addr_buf = malloc((argc -2) * sizeof(struct sockaddr_in6));
+ if (addr_buf == NULL) {
+ perror("bindx_test: ERROR: addr buf allocation failed");
+ return 1;
+ }
+
+ /* Get the addresses from the cmd line */
+ addrs = 0; /* healthy address iterator [and total counter] */
+ cnt = 2; /* argument iterator */
+ buf_ptr = addr_buf;
+ while (cnt < argc) {
+ printf("bindx_test: INFO: Arg %zu: %s", cnt, argv[cnt]);
+ fflush(stderr);
+ if (strchr(argv[cnt], ':')) {
+ struct sockaddr_in6 *sa6;
+
+ sa6 = (struct sockaddr_in6 *)buf_ptr;
+ printf(" IPv6 address number %zu", addrs);
+ sa6->sin6_family = AF_INET6;
+ sa6->sin6_port = port;
+ if (inet_pton(AF_INET6, argv[cnt], &sa6->sin6_addr)) {
+ addrs++;
+ addr_buf_size += sizeof(struct sockaddr_in6);
+ buf_ptr += sizeof(struct sockaddr_in6);
+ } else
+ printf(" error");
+ } else if (strchr(argv[cnt], '.')) {
+ struct sockaddr_in *sa;
+
+ domain = PF_INET;
+ sa = (struct sockaddr_in *)buf_ptr;
+ printf (" IPv4 address number %zu", addrs);
+ sa->sin_family = AF_INET;
+ sa->sin_port = port;
+ if (inet_pton (AF_INET, argv[cnt], &sa->sin_addr)) {
+ addrs++;
+ addr_buf_size += sizeof(struct sockaddr_in);
+ buf_ptr += sizeof(struct sockaddr_in);
+ } else
+ printf (" error");
+ } else
+ printf (" Unknown");
+ putchar ('\n');
+ cnt++;
+ }
+
+ printf ("bindx_test: INFO: Got %zu addrs\n", addrs);
+
+ /* Create the socket */
+ sd = socket(domain, SOCK_SEQPACKET, IPPROTO_SCTP);
+ if (sd == -1) {
+ perror("bindx_test: ERROR: Cannot open socket");
+ return 1;
+ }
+
+ /* add all */
+ result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs,
+ SCTP_BINDX_ADD_ADDR);
+ if (result == -1)
+ perror("bindx_test: ERROR: bindx addition error");
+ else {
+ printf("bindx_test: OK: bindx address addition\n");
+
+ /* remove all but the last */
+ result = sctp_bindx(sd, (struct sockaddr *)addr_buf, addrs-1,
+ SCTP_BINDX_REM_ADDR);
+ if (result == -1)
+ perror("bindx_test: ERROR: bindx address removal");
+ else
+ printf("bindx_test: OK: bindx address removal\n");
+ }
+
+ close(sd);
+ free(addr_buf);
+ return result;
+}
diff --git a/src/apps/myftp.c b/src/apps/myftp.c
new file mode 100644
index 0000000..64fa3f2
--- /dev/null
+++ b/src/apps/myftp.c
@@ -0,0 +1,413 @@
+/* myftp - simple file transfer over sctp testing tool.
+ * Copyright (c) 2002 Intel Corp.
+ *
+ * This file is part of the LKSCTP kernel Implementation. This
+ * is a submission by Xingang Guo from the Intel Corporation while
+ * participating on the LKSCTP project.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <sctp-developers-list@cig.mot.com>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Xingang Guo <xingang.guo@intel.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <errno.h>
+#include <netinet/sctp.h>
+
+#define BUFSIZE 1024
+static char buffer[BUFSIZE];
+#define DUMP_CORE { char *diediedie = 0; *diediedie = 0; }
+
+typedef enum { COMMAND_NONE, COMMAND_RECV, COMMAND_SEND } command_t;
+
+/* These are the global options. */
+#define MAX_NUM_HOST 5
+static char *local_host[MAX_NUM_HOST];
+static int num_local_host = 0;
+static int local_port = 4444;
+
+static int buffer_size = BUFSIZE;
+static char *remote_host = NULL;
+static int remote_port = 4444;
+static command_t command = COMMAND_NONE;
+static char *filename = NULL;
+static int interactive = 0;
+static unsigned long delay = 0;
+static int verbose = 0;
+
+static void
+usage(char *argv0)
+{
+ fprintf(stderr, "Usage: %s [options]\n",argv0);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, "\t--local, -H <hostname> Specify local interface\n");
+ fprintf(stderr, "\t--local-port, -P <port> Specify local port (default 4444)\n");
+ fprintf(stderr, "\t--remote, -h <hostname> Specify interface on remote host\n");
+ fprintf(stderr, "\t--remote-port, -p <port> Specify remote port (default 4444)\n");
+ fprintf(stderr, "\t--listen, -l Work in receiving mode\n");
+ fprintf(stderr, "\t--send, -s Work in sending mode\n");
+ fprintf(stderr, "\t--file, -f <filename> File to read or write,\n");
+ fprintf(stderr, "\t--buffer, -b <size> Buffer size. (default 1024 bytes)\n");
+ fprintf(stderr, "\t by default use standard input/output.\n");
+ fprintf(stderr, "\t--quick, -q Send packets continueously,\n");
+ fprintf(stderr, "\t do not wait for <ENTER> key. Default wait.\n");
+ fprintf(stderr, "\t--delay, -d <usec> Delay between consecutive sends (see --quick)\n");
+ fprintf(stderr, "\t--verbose, -v In verbose mode, display the progress.\n");
+ fprintf(stderr, "\n\t--help, Print this message.\n\n");
+} /* usage() */
+
+static int parse_arguments(int argc, char *argv[])
+{
+ int option_index = 0;
+ int c;
+ static struct option long_options[] = {
+ {"local", 1, 0, 1},
+ {"local-port", 1, 0, 2},
+ {"remote", 1, 0, 3},
+ {"remote-port", 1, 0, 4},
+ {"file", 1, 0, 5},
+ {"delay", 1, 0, 6},
+ {"buffer", 1, 0, 7},
+ {"listen", 0, 0, 10},
+ {"send", 0, 0, 11},
+ {"quick", 0, 0, 12},
+ {"verbose", 0, 0, 13},
+ {"help", 0, 0, 99},
+ {0, 0, 0, 0}
+ };
+
+ /* Parse the arguments. */
+ while (1) {
+ c = getopt_long(argc, argv, "H:P:h:p:f:d:b:qlsv",long_options,&option_index);
+ if (c == -1) break;
+
+ switch (c) {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg) printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+ case 1: /* local host */
+ case 'H':
+ local_host[num_local_host++] = optarg;
+ break;
+ case 2: /* local port */
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 3: /* remote host */
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 4: /* remote port */
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ case 5:
+ case 'f':
+ filename = optarg;
+ break;
+
+ case 6:
+ case 'd':
+ delay = strtoul(optarg,NULL,10);
+ printf("delay is %ld usec\n",delay);
+ break;
+
+ case 7:
+ case 'b':
+ buffer_size = atoi(optarg);
+ if ( buffer_size > BUFSIZE ) {
+ buffer_size = BUFSIZE;
+ fprintf(stderr,"Warning, buffer size too large, set to %d\n",buffer_size);
+ }
+ break;
+
+ case 12:
+ case 'q': interactive = 0; break;
+
+ case 13:
+ case 'v': verbose = 1; break;
+ /* COMMANDS */
+ case 10: /* listen */
+ case 'l':
+ if (command) {
+ fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]);
+ return 1;
+ }
+ else command = COMMAND_RECV;
+ break;
+
+ case 11: /* send */
+ case 's':
+ if (command) {
+ fprintf(stderr, "%s: pick ONE of listen or send\n", argv[0]);
+ return 2;
+ } else command = COMMAND_SEND;
+ break;
+
+ case '?':
+ case 99:
+ usage(argv[0]);
+ return 3;
+ break;
+
+ default:
+ printf ("%s: unrecognized option 0%c\n", argv[0], c);
+ usage(argv[0]);
+ return 4;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]);
+ while (optind < argc) fprintf(stderr, "%s ", argv[optind++]);
+ fprintf(stderr, "\n");
+ usage(argv[0]);
+ return 5;
+ }
+
+
+ if (0 == num_local_host) {
+ fprintf(stderr, "%s: You MUST provide a local host.\n", argv[0]);
+ usage(argv[0]);
+ return 6;
+ }
+
+ if ( filename == NULL && command == COMMAND_SEND)
+ fprintf(stderr,"%s: Use standard input to send\n",argv[0]);
+
+ if ( filename == NULL && command == COMMAND_RECV )
+ fprintf(stderr,"%s: Use standard output to write\n",argv[0]);
+
+ return 0;
+} /* parse_arguments() */
+
+static void
+emsg(char *prog,char *s)
+{
+ if ( prog != NULL ) fprintf(stderr,"%s: ",prog);
+ perror(s);
+ fflush(stdout);
+ //DUMP_CORE;
+
+ exit(-1);
+}
+
+static int build_endpoint(char *argv0)
+{
+ int retval,i;
+
+ /* Create the local endpoint. */
+ if ( (retval = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0 ) {
+ emsg(argv0,"socket");
+ exit(retval);
+ }
+
+ for ( i = 0;i < num_local_host;i++ ) {
+ struct hostent *hst;
+ struct sockaddr_in laddr;
+
+ memset(&laddr, 0, sizeof(laddr));
+ /* Get the transport address for the local host name. */
+ fprintf(stderr,"Hostname %d is %s\n",i+1,local_host[i]);
+ if ( (hst = gethostbyname(local_host[i])) == NULL ) {
+ fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host[i]);
+ exit(1);
+ }
+ memcpy(&laddr.sin_addr, hst->h_addr_list[0],sizeof(laddr.sin_addr));
+ laddr.sin_port = htons(local_port);
+ laddr.sin_family = AF_INET;
+
+ /* Bind this socket to the test port. */
+ if ( bind(retval, (struct sockaddr *)&laddr, sizeof(laddr)) ) {
+ emsg(argv0,"bind");
+ exit(-1);
+ }
+ }
+
+ fprintf(stderr,"Endpoint built.\n");
+
+ return retval;
+} /* build_endpoint() */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+ struct sctp_initmsg init;
+ struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+
+/* Listen on the socket, printing out anything that arrives. */
+static void
+command_recv(char *argv0, int sk)
+{
+ struct msghdr inmessage;
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ int ret;
+ int fd;
+ int ct;
+
+ if (listen(sk, 1) == -1)
+ emsg(argv0, "listen");
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = buffer;
+ iov.iov_len = buffer_size;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /* creat a file */
+ if ( filename == NULL ) fd = 1;
+ else if ( (fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1 )
+ emsg(argv0,"open");
+
+ fprintf(stderr,"%s Receiving...\n", argv0);
+ /* Get the messages sent */
+ ct = 0;
+ while ( (ret = recvmsg(sk, &inmessage, MSG_WAITALL)) >= 0 ) {
+ if ( verbose )
+ fprintf(stderr,"%s-%d received %d bytes\n",
+ argv0, ++ct, ret);
+ if ( !(inmessage.msg_flags & MSG_NOTIFICATION) ) {
+ //printf("%s write %d bytes\n",argv0,ret);
+ if ( write(fd,buffer,ret) != ret ) emsg(argv0,"write");
+ } else {
+ union sctp_notification *sn;
+ sn = (union sctp_notification *)iov.iov_base;
+ if ((sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) &&
+ (sn->sn_assoc_change.sac_state
+ == SCTP_SHUTDOWN_COMP))
+ break;
+ }
+
+ }
+
+ if ( ret < 0 ) emsg(argv0,"recvmsg");
+
+ close(fd);
+ close(sk);
+} /* command_recv() */
+
+/* Read lines from stdin and send them to the socket. */
+static void
+command_send(char *argv0, int sk)
+{
+ struct msghdr outmsg;
+ struct iovec iov;
+ struct hostent *hst;
+ struct sockaddr_in remote_addr;
+ int fd;
+ int msglen;
+ int ct;
+
+ /* Set up the destination. */
+ hst = gethostbyname(remote_host);
+ if (hst == NULL || hst->h_length < 1) {
+ fprintf(stderr, "%s: bad hostname: %s\n", argv0, remote_host);
+ exit(1);
+ }
+ memcpy(&remote_addr.sin_addr, hst->h_addr_list[0], sizeof(remote_addr.sin_addr));
+ remote_addr.sin_port = htons(remote_port);
+ remote_addr.sin_family = AF_INET;
+
+ /* Initialize the message struct we use to pass messages to
+ * the remote socket.
+ */
+ iov.iov_base = buffer;
+ iov.iov_len = buffer_size;
+ outmsg.msg_iov = &iov;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = NULL;
+ outmsg.msg_controllen = 0;
+ outmsg.msg_name = &remote_addr;
+ outmsg.msg_namelen = sizeof(remote_addr);
+
+ /* open the file */
+ if ( filename == NULL ) fd = 0;
+ else if ( (fd = open(filename,O_RDONLY)) == -1 ) emsg(argv0,"open");
+
+ fprintf(stderr,"%s ready to send...\n", argv0);
+ ct = 0;
+ while ( (msglen = read(fd,buffer,buffer_size)) > 0 ) {
+ /* Send to our neighbor. */
+ iov.iov_len = msglen;
+ if ( sendmsg(sk, &outmsg, 0) != msglen ) emsg(argv0,"sendmsg");
+ if ( verbose ) fprintf(stderr,"%s-%d send %d bytes\n",argv0,++ct,msglen);
+ if ( interactive && fd != 1 )
+ getchar();
+ // no flow control? no problem, make it slow
+ else if ( delay > 0 )
+ usleep(delay);
+ }
+
+ close(fd);
+ close(sk);
+} /* command_send() */
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (( ret = parse_arguments(argc, argv) )) return ret;
+
+ switch(command) {
+ case COMMAND_NONE:
+ fprintf(stderr, "%s: Please specify a command.\n", argv[0]);
+ break;
+ case COMMAND_RECV:
+ command_recv(argv[0],build_endpoint(argv[0]));
+ break;
+ case COMMAND_SEND:
+ command_send(argv[0],build_endpoint(argv[0]));
+ break;
+ default:
+ fprintf(stderr, "%s: illegal command %d\n", argv[0], command);
+ } /* switch(command) */
+
+ return 0;
+}
diff --git a/src/apps/nagle_rcv.c b/src/apps/nagle_rcv.c
new file mode 100644
index 0000000..18e0945
--- /dev/null
+++ b/src/apps/nagle_rcv.c
@@ -0,0 +1,243 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a receiver for the performance test to verify Nagle's algorithm.
+ * It creates a socket, binds to a address specified as a parameter and
+ * goes into a receive loop waiting for 1,000,000 packets. Then it calculates
+ * the packet receive rate, i.e. packets/second.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <time.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+void
+usage(char *progname)
+{
+ fprintf(stderr, "Usage: %s -H hostname [-P port]\n", progname);
+ fprintf(stderr, " -H, --local\t\t local hostname,\n");
+ fprintf(stderr, " -P, --local-port\t local port,\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int sk, i;
+ struct addrinfo *hst_res;
+ sockaddr_storage_t host;
+ sockaddr_storage_t msgname;
+ struct iovec iov;
+ struct msghdr inmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ int error, pf_class;
+ char *big_buffer;
+ char *local_host = NULL;
+ int local_port = SCTP_TESTPORT_1;
+ char port_buffer[10];
+ int option_index = 0;
+ time_t from, to;
+ int bytes_received = 0;
+ int c;
+ static struct option long_options[] = {
+ {"local", 1, 0, 1},
+ {"local-port", 1, 0, 2},
+ {0, 0, 0, 0}
+ };
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Parse the arguments. */
+ while (1) {
+ c = getopt_long (argc, argv, "H:P:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ printf("option %s", long_options[option_index].name);
+ if (optarg) {
+ printf(" with arg %s", optarg);
+ }
+ printf("\n");
+ break;
+ case 1: /* local host */
+ case 'H':
+ local_host = optarg;
+ break;
+ case 2: /* local port */
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case '?':
+ usage(argv[0]);
+ exit(0);
+
+ default:
+ printf ("%s: unrecognized option 0%c\n", argv[0], c);
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (optind < argc)
+ {
+ fprintf(stderr, "%s: non-option arguments are illegal: ",
+ argv[0]);
+ while (optind < argc)
+ fprintf(stderr, "%s ", argv[optind++]);
+ fprintf (stderr, "\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (!local_host) {
+ fprintf(stderr, "%s: : option -H, --local is required\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ /* Set some basic values which depend on the address family. */
+ if (!strcmp(local_host, "0"))
+ local_host = "0.0.0.0";
+
+ snprintf(port_buffer, 10, "%d", local_port);
+ error = getaddrinfo(local_host, port_buffer, NULL, &hst_res);
+ if (error) {
+ fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], local_host);
+ exit(1);
+ }
+
+ pf_class = hst_res->ai_family;
+ switch (pf_class) {
+ case AF_INET:
+ case AF_INET6:
+ memcpy(&host.sa, hst_res->ai_addr, hst_res->ai_addrlen);
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+
+ freeaddrinfo(hst_res);
+
+ /* Create the endpoint which will talk to nagle_snd. */
+ sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk);
+
+ /* Bind the sockets to the test port. */
+ test_bind(sk, &host.sa, sizeof(host));
+
+ /* Mark sk as being able to accept new associations. */
+ test_listen(sk, 1);
+
+ printf("Listening on port:%d\n", local_port);
+
+ /* Initialize inmessage for receives. */
+ memset(&inmessage, 0, sizeof(inmessage));
+ big_buffer = test_malloc(REALLY_BIG);
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof(msgname);
+ memset(&msgname, 0, sizeof(msgname));
+
+ /* Get the communication up message on sk. */
+ error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ printf("Established connection with ");
+ if (AF_INET == msgname.sa.sa_family)
+ printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr),
+ ntohs(msgname.v4.sin_port));
+ if (AF_INET6 == msgname.sa.sa_family)
+ printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n",
+ NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port));
+
+ time(&from);
+ for (i=0; i<1000000; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_namelen = sizeof(msgname);
+ error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+ if (inmessage.msg_flags & MSG_NOTIFICATION)
+ break;
+ printf("Received %d bytes of data\n", error);
+ bytes_received += error;
+ }
+ time(&to);
+
+ printf("\t%d messages(%d bytes) successfully received in %ld "
+ "seconds.\n", i, bytes_received, to - from);
+ printf("The receive rate is %ld bytes/second\n",
+ bytes_received/(to - from));
+
+ /* Shut down the link. */
+ error = 0;
+ close(sk);
+
+ return 0;
+}
diff --git a/src/apps/nagle_snd.c b/src/apps/nagle_snd.c
new file mode 100644
index 0000000..bc960cc
--- /dev/null
+++ b/src/apps/nagle_snd.c
@@ -0,0 +1,359 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a receiver for the performance test to verify Nagle's algorithm.
+ * It creates a socket, binds to a address specified as a parameter and
+ * sends 1,000,000 packets to a specified target.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <getopt.h>
+#include <netdb.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+void
+usage(char *argv0)
+{
+ fprintf(stderr, "Usage: %s -H localhost [-P localport] "
+ "-h remotehost [-p remoteport]\n"
+ "\t\t[-S msgsize] [-I interval] -N\n"
+ " -H, --local\t\tspecify one of the local addresses,\n"
+ " -P, --local-port\tspecify the port number for local addresses,\n"
+ " -h, --remote\t\tspecify one of the remote addresses,\n"
+ " -p, --remote-port\tspecify the port number for remote addresses,\n"
+ " -S, --size\t\tspecify the size(byte) of the sending message,\n"
+ " -I, --interval\t\tspecify the interval(second) that sending messages at,\n"
+ " -N, --nodelay\t\tspecify whether the SCTP allows Nagle's algorithm\n",
+ argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int sk, i;
+ struct addrinfo *hst_res, *tgt_res;
+ sockaddr_storage_t host, target;
+ sockaddr_storage_t msgname;
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ char *message;
+ int error, pf_class;
+ sctp_assoc_t associd;
+ uint32_t ppid;
+ uint32_t stream;
+ char *remote_host = NULL;
+ int remote_port = SCTP_TESTPORT_1;
+ char *local_host = NULL;
+ int local_port = SCTP_TESTPORT_2;
+ int size = 1;
+ int interval = 0;
+ int nodelay = 0;
+ int option_index = 0;
+ char *big_buffer;
+ char port_buffer[10];
+ int c;
+ static struct option long_options[] = {
+ {"local", 1, 0, 1},
+ {"local-port", 1, 0, 2},
+ {"remote", 1, 0, 3},
+ {"remote-port", 1, 0, 4},
+ {"size", 1, 0, 5},
+ {"interval", 1, 0, 6},
+ {"nodelay", 0, 0, 10},
+ {0, 0, 0, 0}
+ };
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Parse the arguments. */
+ while (1) {
+ c = getopt_long (argc, argv, "H:P:h:p:S:I:N",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ printf("option %s", long_options[option_index].name);
+ if (optarg) {
+ printf(" with arg %s", optarg);
+ }
+ printf("\n");
+ break;
+ case 1: /* local host */
+ case 'H':
+ local_host = optarg;
+ break;
+ case 2: /* local port */
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 3: /* remote host */
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 4: /* remote port */
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ case 5: /* size */
+ case 'S':
+ size = atoi(optarg);
+ break;
+ case 6: /* interval */
+ case 'I':
+ interval = atoi(optarg);
+ break;
+ case 10: /* nodelay */
+ case 'N':
+ nodelay = 1;
+ break;
+ case '?':
+ usage(argv[0]);
+ exit(0);
+
+ default:
+ printf ("%s: unrecognized option 0%c\n",
+ argv[0], c);
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (optind < argc)
+ {
+ fprintf(stderr, "%s: non-option arguments are illegal: ",
+ argv[0]);
+ while (optind < argc)
+ fprintf(stderr, "%s ", argv[optind++]);
+ fprintf (stderr, "\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (!local_host || !remote_host) {
+ fprintf(stderr, "%s: : option --local and --remote are required\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ /* Set some basic values which depend on the address family. */
+ if (!strcmp(local_host, "0"))
+ local_host = "0.0.0.0";
+
+ snprintf(port_buffer, 10, "%d", local_port);
+ error = getaddrinfo(local_host, port_buffer, NULL, &hst_res);
+ if (error) {
+ fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], local_host);
+ exit(1);
+ }
+
+ snprintf(port_buffer, 10, "%d", remote_port);
+ error = getaddrinfo(remote_host, port_buffer, NULL, &tgt_res);
+ if (error) {
+ fprintf(stderr, "%s: getaddrinfo failed: %s\n", argv[0], remote_host);
+ exit(1);
+ }
+
+ if ( hst_res->ai_family != tgt_res->ai_family) {
+ fprintf(stderr, "local and reomte hosts should be the "
+ "same address family\n");
+ exit(1);
+ }
+
+ pf_class = hst_res->ai_family;
+ switch (pf_class) {
+ case AF_INET:
+ case AF_INET6:
+ memcpy(&host.sa, hst_res->ai_addr, hst_res->ai_addrlen);
+ memcpy(&target.sa, tgt_res->ai_addr, tgt_res->ai_addrlen);
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+
+ freeaddrinfo(hst_res);
+ freeaddrinfo(tgt_res);
+
+ sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk);
+
+ test_setsockopt(sk, SCTP_NODELAY, &nodelay, sizeof(int));
+
+ /* Bind the sockets to the test port. */
+ test_bind(sk, &host.sa, sizeof(host));
+
+ /* Mark sk as being able to accept new associations. */
+ test_listen(sk, 1);
+
+ /* Build up a msghdr structure we can use for all sending. */
+ outmessage.msg_name = ⌖
+ outmessage.msg_namelen = sizeof(target);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+
+ message = test_malloc((size + 1) * sizeof(u_int8_t));
+
+ for(i=0; i + 10 < size; i+= 10)
+ memcpy(message+i, "1234567890", 10);
+ strncpy(message+i, "1234567890", size-i);
+ *(message+size) = 0;
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = size + 1;
+
+ printf("Initiating connection with %s:%d...\n", remote_host,
+ remote_port);
+
+ /* Send the first message. This will create the association. */
+ test_sendmsg(sk, &outmessage, 0, size+1);
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ big_buffer = test_malloc(REALLY_BIG);
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof(msgname);
+ memset(&msgname, 0, sizeof(msgname));
+
+ /* Get the communication up message on sk. */
+ error = test_recvmsg(sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ associd = ((struct sctp_assoc_change *)iov.iov_base)->sac_assoc_id;
+
+ printf("Established connection with ");
+ if (AF_INET == msgname.sa.sa_family)
+ printf("%d.%d.%d.%d(%d)\n", NIPQUAD(msgname.v4.sin_addr),
+ ntohs(msgname.v4.sin_port));
+ if (AF_INET6 == msgname.sa.sa_family)
+ printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x(%d)\n",
+ NIP6(msgname.v6.sin6_addr), ntohs(msgname.v6.sin6_port));
+
+ printf("Sending data to receiver...\n");
+
+ for (i=1; i<1000000; i++) {
+
+ if (interval)
+ sleep(interval);
+
+ outmessage.msg_name = ⌖
+ outmessage.msg_namelen = sizeof(target);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ ppid++;
+
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ sinfo->sinfo_assoc_id = associd;
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = size + 1;
+
+ test_sendmsg(sk, &outmessage, 0, size+1);
+ }
+
+ printf("\n\n\t\tComplete all the data sendings to receiver...\n\n\n");
+
+ error = 0;
+ close(sk);
+
+ free(message);
+
+ /* Indicate successful completion. */
+ return 0;
+
+}
diff --git a/src/apps/peel_client.c b/src/apps/peel_client.c
new file mode 100644
index 0000000..5c195d3
--- /dev/null
+++ b/src/apps/peel_client.c
@@ -0,0 +1,672 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * In addition:
+ *
+ * Copyright (c) 2003 Cisco
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * a) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * b) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * c) Neither the name of Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Randall Stewart <rrs@cisco.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <netdb.h>
+
+#include <netinet/sctp.h>
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+
+#define SCTP_CRC32C_POLY 0x1EDC6F41
+#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Copyright 2001, D. Otis. Use this program, code or tables */
+/* extracted from it, as desired without restriction. */
+/* */
+/* 32 Bit Reflected CRC table generation for SCTP. */
+/* To accommodate serial byte data being shifted out least */
+/* significant bit first, the table's 32 bit words are reflected */
+/* which flips both byte and bit MS and LS positions. The CRC */
+/* is calculated MS bits first from the perspective of the serial*/
+/* stream. The x^32 term is implied and the x^0 term may also */
+/* be shown as +1. The polynomial code used is 0x1EDC6F41. */
+/* Castagnoli93 */
+/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+ */
+/* x^11+x^10+x^9+x^8+x^6+x^0 */
+/* Guy Castagnoli Stefan Braeuer and Martin Herrman */
+/* "Optimization of Cyclic Redundancy-Check Codes */
+/* with 24 and 32 Parity Bits", */
+/* IEEE Transactions on Communications, Vol.41, No.6, June 1993 */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static unsigned char buffer1[4100];
+static unsigned char buffer2[4100];
+static unsigned char buffer3[4100];
+static unsigned char buffer4[4100];
+static struct sockaddr_in bindto,got,to;
+static socklen_t len;
+
+unsigned long sctp_crc_c[256] = {
+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+ 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+ 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+ 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+ 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+ 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+ 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+ 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+ 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+ 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+ 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+ 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+ 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+ 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+ 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+ 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+ 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+ 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+ 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+ 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+ 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+ 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+ 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+ 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+ 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+ 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+ 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+ 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+ 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+ 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+ 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+ 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+ 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+ 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+ 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+ 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+ 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+ 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+ 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+ 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+ 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+ 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+ 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+ 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+ 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+ 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+ 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+ 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+ 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+ 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+ 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+ 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+};
+
+u_int32_t
+update_crc32(u_int32_t crc32,
+ unsigned char *buffer,
+ unsigned int length)
+{
+ int i;
+ for (i = 0; i < length; i++) {
+ SCTP_CRC32C(crc32, buffer[i]);
+ }
+ return (crc32);
+}
+
+u_int32_t
+sctp_csum_finalize(u_int32_t crc32)
+{
+ u_int32_t result;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t byte0, byte1, byte2, byte3;
+#endif
+ /* Complement the result */
+ result = ~crc32;
+#if BYTE_ORDER == BIG_ENDIAN
+ /*
+ * For BIG-ENDIAN.. aka Motorola byte order the result is in
+ * little-endian form. So we must manually swap the bytes. Then
+ * we can call htonl() which does nothing...
+ */
+ byte0 = result & 0x000000ff;
+ byte1 = (result >> 8) & 0x000000ff;
+ byte2 = (result >> 16) & 0x000000ff;
+ byte3 = (result >> 24) & 0x000000ff;
+ result = ((byte0 << 24) |
+ (byte1 << 16) |
+ (byte2 << 8) |
+ byte3);
+ crc32 = htonl(result);
+#else
+ /*
+ * For INTEL platforms the result comes out in network order.
+ * No htonl is required or the swap above. So we optimize out
+ * both the htonl and the manual swap above.
+ */
+ crc32 = result;
+#endif
+ return (crc32);
+}
+
+static u_int32_t at = 468700;
+
+void
+prepare_buffers(void)
+{
+ /* Prepare buffers */
+ u_int32_t temp,*p;
+ int i;
+
+ p = (u_int32_t *)buffer1;
+ for(i=0;i<(sizeof(buffer1)/4);i++){
+ *p = at;
+ at++;
+ p++;
+ }
+ /* backup over the last int */
+ p--;
+ *p = 0;
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4));
+ *p = sctp_csum_finalize(temp);
+
+ p = (u_int32_t *)buffer2;
+ for(i=0;i<(sizeof(buffer2)/4);i++){
+ *p = at;
+ at++;
+ p++;
+ }
+ p--;
+ *p = 0;
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4));
+ *p = sctp_csum_finalize(temp);
+
+ p = (u_int32_t *)buffer3;
+ for(i=0;i<(sizeof(buffer3)/4);i++){
+ *p = at;
+ at++;
+ p++;
+ }
+ p--;
+ *p = 0;
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4));
+ *p = sctp_csum_finalize(temp);
+
+ p = (u_int32_t *)buffer4;
+ for(i=0;i<(sizeof(buffer4)/4);i++){
+ *p = at;
+ at++;
+ p++;
+ }
+ p--;
+ *p = 0;
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4));
+ *p = sctp_csum_finalize(temp);
+}
+
+static int
+my_handle_notification(int fd,char *notify_buf) {
+ union sctp_notification *snp;
+ struct sctp_assoc_change *sac;
+ struct sctp_paddr_change *spc;
+ struct sctp_remote_error *sre;
+ struct sctp_send_failed *ssf;
+ struct sctp_shutdown_event *sse;
+ int asocDown;
+ char *str;
+ char buf[256];
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ asocDown = 0;
+ snp = (union sctp_notification *)notify_buf;
+ switch(snp->sn_header.sn_type) {
+ case SCTP_ASSOC_CHANGE:
+ sac = &snp->sn_assoc_change;
+ switch(sac->sac_state) {
+
+ case SCTP_COMM_UP:
+ str = "COMMUNICATION UP";
+ break;
+ case SCTP_COMM_LOST:
+ str = "COMMUNICATION LOST";
+ asocDown = 1;
+ break;
+ case SCTP_RESTART:
+ str = "RESTART";
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ str = "SHUTDOWN COMPLETE";
+ asocDown = 1;
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ str = "CANT START ASSOC";
+ printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+ (uint32_t)sac->sac_assoc_id);
+ exit(0);
+ break;
+ default:
+ str = "UNKNOWN";
+ } /* end switch(sac->sac_state) */
+ printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+ (uint32_t)sac->sac_assoc_id);
+ break;
+ case SCTP_PEER_ADDR_CHANGE:
+ spc = &snp->sn_paddr_change;
+ switch(spc->spc_state) {
+ case SCTP_ADDR_AVAILABLE:
+ str = "ADDRESS AVAILABLE";
+ break;
+ case SCTP_ADDR_UNREACHABLE:
+ str = "ADDRESS UNAVAILABLE";
+ break;
+ case SCTP_ADDR_REMOVED:
+ str = "ADDRESS REMOVED";
+ break;
+ case SCTP_ADDR_ADDED:
+ str = "ADDRESS ADDED";
+ break;
+ case SCTP_ADDR_MADE_PRIM:
+ str = "ADDRESS MADE PRIMARY";
+ break;
+ default:
+ str = "UNKNOWN";
+ } /* end switch */
+ sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+ if (sin6->sin6_family == AF_INET6) {
+ inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf));
+ } else {
+ sin = (struct sockaddr_in *)&spc->spc_aaddr;
+ inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf));
+ }
+ printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str,
+ buf, (uint32_t)spc->spc_assoc_id);
+ break;
+ case SCTP_REMOTE_ERROR:
+ sre = &snp->sn_remote_error;
+ printf("SCTP_REMOTE_ERROR: assoc=%xh\n",
+ (uint32_t)sre->sre_assoc_id);
+ break;
+ case SCTP_SEND_FAILED:
+ ssf = &snp->sn_send_failed;
+ printf("SCTP_SEND_FAILED: assoc=%xh\n",
+ (uint32_t)ssf->ssf_assoc_id);
+ break;
+ case SCTP_ADAPTATION_INDICATION:
+ {
+ struct sctp_adaptation_event *ae;
+ ae = &snp->sn_adaptation_event;
+ printf("\nSCTP_adaptation_indication bits:0x%x\n",
+ (u_int)ae->sai_adaptation_ind);
+ }
+ break;
+ case SCTP_PARTIAL_DELIVERY_EVENT:
+ {
+ struct sctp_pdapi_event *pdapi;
+ pdapi = &snp->sn_pdapi_event;
+ printf("SCTP_PD-API event:%u\n",
+ pdapi->pdapi_indication);
+ if(pdapi->pdapi_indication == 0){
+ printf("PDI- Aborted\n");
+ }
+ }
+ break;
+
+ case SCTP_SHUTDOWN_EVENT:
+ sse = &snp->sn_shutdown_event;
+ printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n",
+ (uint32_t)sse->sse_assoc_id);
+ break;
+ default:
+ printf("Unknown notification event type=%xh\n",
+ snp->sn_header.sn_type);
+ } /* end switch(snp->sn_type) */
+ if(asocDown){
+ printf("Bring association back up\n");
+ len = sizeof(to);
+ if(connect(fd,(struct sockaddr *)&to,len) == -1){
+ printf("Sorry connect fails %d\n",errno);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+
+
+int
+my_sctpReadInput(int fd)
+{
+ /* receive some number of datagrams and
+ * act on them.
+ */
+ int sz;
+ struct msghdr msg;
+ struct iovec iov[2];
+ unsigned char from[200];
+ char readBuffer[65535];
+ char controlVector[65535];
+
+ iov[0].iov_base = readBuffer;
+ iov[0].iov_len = sizeof(readBuffer);
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ msg.msg_name = (caddr_t)from;
+ msg.msg_namelen = sizeof(from);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)controlVector;
+ msg.msg_controllen = sizeof(controlVector);
+ msg.msg_flags = 0;
+ errno = 0;
+ sz = recvmsg(fd,&msg,0);
+ if(sz <= 0){
+ printf("Read returns %d errno:%d control len is %zu msgflg:%x\n",
+ sz,errno,
+ msg.msg_controllen,msg.msg_flags);
+ }
+ if (msg.msg_flags & MSG_NOTIFICATION) {
+ return(my_handle_notification(fd,readBuffer));
+ }else{
+ printf("Huh, I got data?.. ignored (%d bytes)\n",sz);
+ return(0);
+ }
+}
+
+
+int
+clear_fds(int fd,int fd1)
+{
+ int felldown;
+ int max,notdone;
+ fd_set readfds,writefds,exceptfds;
+ struct timeval tv;
+ memset(&tv,0,sizeof(tv));
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ felldown = 0;
+ FD_SET(fd,&readfds);
+ FD_SET(fd1,&readfds);
+ if(fd > fd1){
+ max = fd + 1;
+ }else{
+ max = fd1 + 1;
+ }
+ notdone = 1;
+ while(notdone){
+ if (select(max, &readfds, &writefds, &exceptfds, &tv) == -1)
+ break;
+ notdone = 0;
+ if(FD_ISSET(fd,&readfds)){
+ notdone++;
+ printf("clearing fd:%d\n",fd);
+ felldown += my_sctpReadInput(fd);
+ notdone = 1;
+ }
+ if(FD_ISSET(fd1,&readfds)){
+ notdone++;
+ printf("clearing fd1:%d\n",fd1);
+ felldown += my_sctpReadInput(fd1);
+ }
+ }
+ return(felldown);
+}
+
+void
+process_out_data(int fd,int fd1)
+{
+ int notdone,x,ret;
+ while(1){
+ /* Prepare the buffers */
+ prepare_buffers();
+ /* send out the 4 buffers */
+ ret = sendto(fd,buffer1,sizeof(buffer1),0,
+ (struct sockaddr *)&to,sizeof(to));
+ if(ret < sizeof(buffer1)){
+ printf("Gak1, error:%d ret:%d\n",errno,ret);
+ }
+
+ ret = sendto(fd1,buffer2,sizeof(buffer1),0,
+ (struct sockaddr *)&to,sizeof(to));
+ if(ret < sizeof(buffer2)){
+ printf("Gak2, error:%d ret:%d\n",errno,ret);
+ }
+
+
+ ret = sendto(fd,buffer3,sizeof(buffer1),0,
+ (struct sockaddr *)&to,sizeof(to));
+ if(ret < sizeof(buffer3)){
+ printf("Gak3, error:%d ret:%d\n",errno,ret);
+ }
+
+
+ ret = sendto(fd1,buffer4,sizeof(buffer1),0,
+ (struct sockaddr *)&to,sizeof(to));
+ if(ret < sizeof(buffer4)){
+ printf("Gak4, error:%d ret:%d\n",errno,ret);
+ }
+
+ /* now wait until we get a assoc failing */
+ notdone = 1;
+ while(notdone){
+ x = clear_fds(fd,fd1);
+ if(x){
+ notdone = 0;
+ }
+ sleep(1);
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int i,fd,fd1;
+ char *addr=NULL;
+ uint16_t port=0;
+ int protocol_touse = IPPROTO_SCTP;
+ struct sctp_event_subscribe event = {0};
+
+ while((i= getopt(argc,argv,"p:h:")) != EOF){
+ switch(i){
+ case 'h':
+ addr = optarg;
+ break;
+ case 'p':
+ port = (uint16_t)strtol(optarg,NULL,0);
+ break;
+ };
+ }
+ memset(&to,0,sizeof(to));
+ if((addr == NULL) || (port == 0)){
+ printf("Usage: %s -h addr -p port\n", argv[0]);
+ return(-1);
+ }
+ if(inet_pton(AF_INET, addr, (void *) &to.sin_addr)){
+ //to.sin_len = sizeof(to);
+ to.sin_family = AF_INET;
+ printf("port selected is %d\n",port);
+ printf("addr %x\n",(u_int)ntohl(to.sin_addr.s_addr));
+ to.sin_port = htons(port);
+ }else{
+ printf("Can't translate the address\n");
+ return(-1);
+ }
+ /**********************socket 1 *******************/
+ fd = socket(AF_INET, SOCK_SEQPACKET, protocol_touse);
+ if(fd == -1){
+ printf("can't open socket:%d\n",errno);
+ return(-1);
+ }
+ memset(&bindto,0,sizeof(bindto));
+ //len = bindto.sin_len = sizeof(bindto);
+ len = sizeof(bindto);
+ bindto.sin_family = AF_INET;
+ bindto.sin_port = 0;
+ if(bind(fd,(struct sockaddr *)&bindto, len) < 0){
+ printf("can't bind a socket:%d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){
+ printf("get sockname failed err:%d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ printf("fd uses port %d\n",ntohs(got.sin_port));
+
+ /**********************socket 2 *******************/
+ fd1 = socket(AF_INET, SOCK_SEQPACKET, protocol_touse);
+ if(fd1 == -1){
+ printf("can't open socket:%d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ memset(&bindto,0,sizeof(bindto));
+ //len = bindto.sin_len = sizeof(bindto);
+ len = sizeof(bindto);
+ bindto.sin_family = AF_INET;
+ bindto.sin_port = 0;
+ if(bind(fd1,(struct sockaddr *)&bindto, len) < 0){
+ printf("can't bind a socket:%d\n",errno);
+ close(fd);
+ close(fd1);
+ return(-1);
+ }
+ if(getsockname(fd1,(struct sockaddr *)&got,&len) < 0){
+ printf("get sockname failed err:%d\n",errno);
+ close(fd);
+ close(fd1);
+ return(-1);
+ }
+ printf("fd1 uses port %d\n",ntohs(got.sin_port));
+
+ /* enable all event notifications */
+ event.sctp_data_io_event = 1;
+ event.sctp_association_event = 1;
+ event.sctp_address_event = 1;
+ event.sctp_send_failure_event = 1;
+ event.sctp_peer_error_event = 1;
+ event.sctp_shutdown_event = 1;
+ event.sctp_partial_delivery_event = 1;
+ event.sctp_adaptation_layer_event = 1;
+ if (setsockopt(fd, IPPROTO_SCTP,
+ SCTP_EVENTS, &event,
+ sizeof(event)) != 0) {
+ printf("Gak, can't set events errno:%d\n",errno);
+ exit(0);
+ }
+ if (setsockopt(fd1, IPPROTO_SCTP,
+ SCTP_EVENTS, &event,
+ sizeof(event)) != 0) {
+ printf("Gak, can't set events errno:%d\n",errno);
+ exit(0);
+ }
+
+ if(connect(fd,(struct sockaddr *)&to,len) == -1){
+ printf("Sorry connect fails %d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ if(connect(fd1,(struct sockaddr *)&to,len) == -1){
+ printf("Sorry connect fails %d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ printf("Connected\n");
+ clear_fds(fd,fd1);
+ process_out_data(fd,fd1);
+
+ return(0);
+}
+
diff --git a/src/apps/peel_server.c b/src/apps/peel_server.c
new file mode 100644
index 0000000..24a1ef8
--- /dev/null
+++ b/src/apps/peel_server.c
@@ -0,0 +1,667 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2003 Cisco
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * In addition:
+ *
+ * Copyright (c) 2003 Cisco
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * a) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * b) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * c) Neither the name of Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Randall Stewart <rrs@cisco.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <netdb.h>
+
+#include <netinet/sctp.h>
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+
+#define SCTP_CRC32C_POLY 0x1EDC6F41
+#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Copyright 2001, D. Otis. Use this program, code or tables */
+/* extracted from it, as desired without restriction. */
+/* */
+/* 32 Bit Reflected CRC table generation for SCTP. */
+/* To accommodate serial byte data being shifted out least */
+/* significant bit first, the table's 32 bit words are reflected */
+/* which flips both byte and bit MS and LS positions. The CRC */
+/* is calculated MS bits first from the perspective of the serial*/
+/* stream. The x^32 term is implied and the x^0 term may also */
+/* be shown as +1. The polynomial code used is 0x1EDC6F41. */
+/* Castagnoli93 */
+/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+ */
+/* x^11+x^10+x^9+x^8+x^6+x^0 */
+/* Guy Castagnoli Stefan Braeuer and Martin Herrman */
+/* "Optimization of Cyclic Redundancy-Check Codes */
+/* with 24 and 32 Parity Bits", */
+/* IEEE Transactions on Communications, Vol.41, No.6, June 1993 */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static unsigned char buffer1[4100];
+static unsigned char buffer2[4100];
+static unsigned char buffer3[4100];
+static unsigned char buffer4[4100];
+static struct sockaddr_in bindto,got;
+static socklen_t len;
+
+unsigned long sctp_crc_c[256] = {
+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+ 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+ 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+ 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+ 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+ 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+ 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+ 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+ 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+ 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+ 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+ 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+ 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+ 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+ 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+ 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+ 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+ 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+ 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+ 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+ 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+ 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+ 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+ 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+ 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+ 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+ 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+ 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+ 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+ 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+ 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+ 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+ 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+ 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+ 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+ 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+ 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+ 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+ 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+ 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+ 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+ 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+ 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+ 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+ 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+ 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+ 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+ 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+ 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+ 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+ 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+ 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
+};
+
+u_int32_t
+update_crc32(u_int32_t crc32,
+ unsigned char *buffer,
+ unsigned int length)
+{
+ int i;
+ for (i = 0; i < length; i++) {
+ SCTP_CRC32C(crc32, buffer[i]);
+ }
+ return (crc32);
+}
+
+u_int32_t
+sctp_csum_finalize(u_int32_t crc32)
+{
+ u_int32_t result;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int8_t byte0, byte1, byte2, byte3;
+#endif
+ /* Complement the result */
+ result = ~crc32;
+#if BYTE_ORDER == BIG_ENDIAN
+ /*
+ * For BIG-ENDIAN.. aka Motorola byte order the result is in
+ * little-endian form. So we must manually swap the bytes. Then
+ * we can call htonl() which does nothing...
+ */
+ byte0 = result & 0x000000ff;
+ byte1 = (result >> 8) & 0x000000ff;
+ byte2 = (result >> 16) & 0x000000ff;
+ byte3 = (result >> 24) & 0x000000ff;
+ result = ((byte0 << 24) |
+ (byte1 << 16) |
+ (byte2 << 8) |
+ byte3);
+ crc32 = htonl(result);
+#else
+ /*
+ * For INTEL platforms the result comes out in network order.
+ * No htonl is required or the swap above. So we optimize out
+ * both the htonl and the manual swap above.
+ */
+ crc32 = result;
+#endif
+ return (crc32);
+}
+
+int
+check_buffers(void)
+{
+ /* Prepare buffers */
+ u_int32_t temp,*csum;
+ int ret=0;
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer1,(sizeof(buffer1)-4));
+ temp = sctp_csum_finalize(temp);
+ csum = (u_int32_t *)(buffer1+(sizeof(buffer1)-4));
+ if(*csum != temp){
+ printf("Buffer1: Found csum:%x calculated:%x\n",
+ *csum,temp);
+ ret++;
+ }
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer2,(sizeof(buffer2)-4));
+ temp = sctp_csum_finalize(temp);
+ csum = (u_int32_t *)(buffer2+(sizeof(buffer2)-4));
+ if(*csum != temp){
+ printf("Buffer2: Found csum:%x calculated:%x\n",
+ *csum,temp);
+ ret++;
+ }
+
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer3,(sizeof(buffer3)-4));
+ temp = sctp_csum_finalize(temp);
+ csum = (u_int32_t *)(buffer3+(sizeof(buffer3)-4));
+ if(*csum != temp){
+ printf("Buffer3: Found csum:%x calculated:%x\n",
+ *csum,temp);
+ ret++;
+ }
+
+ temp = 0xffffffff;
+ temp = update_crc32(temp,buffer4,(sizeof(buffer4)-4));
+ temp = sctp_csum_finalize(temp);
+ csum = (u_int32_t *)(buffer4+(sizeof(buffer4)-4));
+ if(*csum != temp){
+ printf("Buffer4: Found csum:%x calculated:%x\n",
+ *csum,temp);
+ ret++;
+ }
+ return(ret);
+}
+
+static int
+my_handle_notification(int fd,char *notify_buf) {
+ union sctp_notification *snp;
+ struct sctp_assoc_change *sac;
+ struct sctp_paddr_change *spc;
+ struct sctp_remote_error *sre;
+ struct sctp_send_failed *ssf;
+ struct sctp_shutdown_event *sse;
+ int asocUp;
+ char *str;
+ char buf[256];
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ snp = (union sctp_notification *)notify_buf;
+ asocUp = 0;
+ switch(snp->sn_header.sn_type) {
+ case SCTP_ASSOC_CHANGE:
+ sac = &snp->sn_assoc_change;
+ switch(sac->sac_state) {
+
+ case SCTP_COMM_UP:
+ str = "COMMUNICATION UP";
+ asocUp++;
+ break;
+ case SCTP_COMM_LOST:
+ str = "COMMUNICATION LOST";
+ break;
+ case SCTP_RESTART:
+ str = "RESTART";
+ asocUp++;
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ str = "SHUTDOWN COMPLETE";
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ str = "CANT START ASSOC";
+ printf("EXIT:SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+ (uint32_t)sac->sac_assoc_id);
+ exit(0);
+ break;
+ default:
+ str = "UNKNOWN";
+ } /* end switch(sac->sac_state) */
+ printf("SCTP_ASSOC_CHANGE: %s, assoc=%xh\n", str,
+ (uint32_t)sac->sac_assoc_id);
+ break;
+ case SCTP_PEER_ADDR_CHANGE:
+ spc = &snp->sn_paddr_change;
+ switch(spc->spc_state) {
+ case SCTP_ADDR_AVAILABLE:
+ str = "ADDRESS AVAILABLE";
+ break;
+ case SCTP_ADDR_UNREACHABLE:
+ str = "ADDRESS UNAVAILABLE";
+ break;
+ case SCTP_ADDR_REMOVED:
+ str = "ADDRESS REMOVED";
+ break;
+ case SCTP_ADDR_ADDED:
+ str = "ADDRESS ADDED";
+ break;
+ case SCTP_ADDR_MADE_PRIM:
+ str = "ADDRESS MADE PRIMARY";
+ break;
+ default:
+ str = "UNKNOWN";
+ } /* end switch */
+ sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+ if (sin6->sin6_family == AF_INET6) {
+ inet_ntop(AF_INET6, (char*)&sin6->sin6_addr, buf, sizeof(buf));
+ } else {
+ sin = (struct sockaddr_in *)&spc->spc_aaddr;
+ inet_ntop(AF_INET, (char*)&sin->sin_addr, buf, sizeof(buf));
+ }
+ printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=%xh\n", str,
+ buf, (uint32_t)spc->spc_assoc_id);
+ break;
+ case SCTP_REMOTE_ERROR:
+ sre = &snp->sn_remote_error;
+ printf("SCTP_REMOTE_ERROR: assoc=%xh\n",
+ (uint32_t)sre->sre_assoc_id);
+ break;
+ case SCTP_SEND_FAILED:
+ ssf = &snp->sn_send_failed;
+ printf("SCTP_SEND_FAILED: assoc=%xh\n",
+ (uint32_t)ssf->ssf_assoc_id);
+ break;
+ case SCTP_ADAPTATION_INDICATION:
+ {
+ struct sctp_adaptation_event *ae;
+ ae = &snp->sn_adaptation_event;
+ printf("\nSCTP_adaptation_indication bits:0x%x\n",
+ (u_int)ae->sai_adaptation_ind);
+ }
+ break;
+ case SCTP_PARTIAL_DELIVERY_EVENT:
+ {
+ struct sctp_pdapi_event *pdapi;
+ pdapi = &snp->sn_pdapi_event;
+ printf("SCTP_PD-API event:%u\n",
+ pdapi->pdapi_indication);
+ if(pdapi->pdapi_indication == 0){
+ printf("PDI- Aborted\n");
+ }
+ }
+ break;
+
+ case SCTP_SHUTDOWN_EVENT:
+ sse = &snp->sn_shutdown_event;
+ printf("SCTP_SHUTDOWN_EVENT: assoc=%xh\n",
+ (uint32_t)sse->sse_assoc_id);
+ break;
+ default:
+ printf("Unknown notification event type=%xh\n",
+ snp->sn_header.sn_type);
+ } /* end switch(snp->sn_type) */
+ return(asocUp);
+}
+
+
+static char readBuffer[65535];
+static int sz=0;
+static char controlVector[65535];
+static struct msghdr msg;
+int
+my_sctpReadInput(int fd,int maxread)
+{
+ /* receive some number of datagrams and
+ * act on them.
+ */
+ struct iovec iov[2];
+ unsigned char from[200];
+
+ memset(&msg,0,sizeof(msg));
+ memset(controlVector,0,sizeof(controlVector));
+ memset(readBuffer,0,sizeof(readBuffer));
+
+ iov[0].iov_base = readBuffer;
+ iov[0].iov_len = maxread;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ msg.msg_name = (caddr_t)from;
+ msg.msg_namelen = sizeof(from);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)controlVector;
+ msg.msg_controllen = sizeof(controlVector);
+ errno = 0;
+ sz = recvmsg(fd,&msg,0);
+ printf("Read fd:%d returns %d errno:%d control len is %zu msgflg:%x\n",
+ fd,
+ sz,errno,
+ msg.msg_controllen,
+ msg.msg_flags);
+
+ if (msg.msg_flags & MSG_NOTIFICATION) {
+ printf("Got a notification\n");
+ return(my_handle_notification(fd,readBuffer));
+ }else{
+ printf("Got data\n");
+ return(-1);
+ }
+}
+
+
+int
+poll_fd(int fd)
+{
+ int cameup;
+ int max;
+ fd_set readfds,writefds,exceptfds;
+ struct timeval tv;
+
+ memset(&tv,0,sizeof(tv));
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ cameup = 0;
+ max = fd + 1;
+
+ printf("poll_fd\n");
+ FD_SET(fd,&readfds);
+
+ if (select(max, &readfds, &writefds, &exceptfds, NULL) == -1)
+ return(cameup);
+ if(FD_ISSET(fd,&readfds)){
+ printf("Read please\n");
+ cameup += my_sctpReadInput(fd,4100);
+ }
+
+ return(cameup);
+}
+
+static sctp_assoc_t
+dig_out_asocid(void)
+{
+ struct sctp_sndrcvinfo *s_info;
+ struct cmsghdr *cmsg;
+ s_info = NULL;
+ if(msg.msg_controllen){
+ /* parse through and see if we find
+ * the sctp_sndrcvinfo
+ */
+ cmsg = (struct cmsghdr *)controlVector;
+ while(cmsg){
+ if(cmsg->cmsg_level == IPPROTO_SCTP){
+ if(cmsg->cmsg_type == SCTP_SNDRCV){
+ /* Got it */
+ s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ break;
+ }
+ }
+ cmsg = CMSG_NXTHDR(&msg,cmsg);
+ }
+ }else{
+ printf("No CMSG?\n");
+ exit(0);
+ }
+ if(s_info == NULL){
+ printf("No sinfo?\n");
+ exit(0);
+ }
+ return(s_info->sinfo_assoc_id);
+}
+
+
+void
+process(int fd,int magic)
+{
+ int fd1,num_asoc,ret,i;
+ sctp_assoc_t asoc;
+ struct timespec ts;
+ num_asoc = 0;
+ i = 1;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 10000;
+
+ while(i < 4099){
+ printf("pass %d\n",i);
+ while(num_asoc < 2){
+ ret = poll_fd(fd);
+ if(ret >0 ){
+ num_asoc += ret;
+ }else if(ret == 0){
+ sleep(1);
+ }else if(ret < 0){
+ printf("Got data? %d\n",sz);
+ sleep(1);
+ }
+ printf("asoc count is %d\n",num_asoc);
+ }
+ again:
+ printf("Reading for %d bytes from fd:%d\n",
+ i,fd);
+ my_sctpReadInput(fd,i);
+ if(sz == i){
+ memcpy(buffer1,readBuffer,i);
+ }else{
+ printf("Huh I am messed up read %d wanted %d\n",
+ sz,i);
+ goto again;
+ }
+ if(msg.msg_flags & MSG_EOR){
+ printf("Huh got EOR on paritial read?\n");
+ exit(0);
+ }
+ asoc = dig_out_asocid();
+ nanosleep(&ts,NULL);
+
+ fd1 = sctp_peeloff(fd,asoc);
+ if(fd1 == -1){
+ printf("peeloff failed %d/err:%d\n",
+ fd1,errno);
+ exit(0);
+ }
+ my_sctpReadInput(fd1,(4100-i));
+ if(sz > 0){
+ memcpy(&buffer1[i],readBuffer,sz);
+ printf("Copied %d bytes\n",sz);
+ }else{
+ printf("Huh only read %d\n",sz);
+ }
+ if(magic >= i){
+ printf("magic engaged\n");
+ my_sctpReadInput(fd,i);
+ }else{
+ my_sctpReadInput(fd,4100);
+ }
+ if(sz > 0){
+ memcpy(buffer2,readBuffer,sz);
+ printf("copied %d bytes\n",sz);
+ }else{
+ printf("Huh only read %d\n",sz);
+ }
+ my_sctpReadInput(fd1,4100);
+ if(sz > 0){
+ memcpy(buffer3,readBuffer,sz);
+ printf("copied %d bytes\n",sz);
+ }else{
+ printf("Huh only read %d\n",sz);
+ }
+ my_sctpReadInput(fd,4100);
+ if(sz > 0){
+ memcpy(buffer4,readBuffer,sz);
+ printf("copied %d bytes\n",sz);
+ }else{
+ printf("Huh only read %d\n",sz);
+ }
+ if(check_buffers()){
+ exit(0);
+ }
+ close(fd1);
+ i++;
+ num_asoc--;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int i,fd;
+ uint16_t myport=0;
+ int magic=0;
+ struct sctp_event_subscribe event = {0};
+ while((i= getopt(argc,argv,"m:M:")) != EOF){
+ switch(i){
+ case 'm':
+ myport = (uint16_t)strtol(optarg,NULL,0);
+ break;
+ case 'M':
+ magic = strtol(optarg,NULL,0);
+ break;
+ };
+ }
+ /**********************socket 1 *******************/
+ fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ if(fd == -1){
+ printf("can't open socket:%d\n",errno);
+ return(-1);
+ }
+ memset(&bindto,0,sizeof(bindto));
+ //len = bindto.sin_len = sizeof(bindto);
+ len = sizeof(bindto);
+ bindto.sin_family = AF_INET;
+ printf("bind port %d\n",myport);
+ bindto.sin_port = htons(myport);
+ if(bind(fd,(struct sockaddr *)&bindto, len) < 0){
+ printf("can't bind a socket:%d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ if(getsockname(fd,(struct sockaddr *)&got,&len) < 0){
+ printf("get sockname failed err:%d\n",errno);
+ close(fd);
+ return(-1);
+ }
+ printf("fd uses port %d\n",ntohs(got.sin_port));
+ if (listen(fd, 100) == -1) {
+ printf("listen err: %d\n", errno);
+ close(fd);
+ return(-1);
+ }
+ /* enable all event notifications */
+ event.sctp_data_io_event = 1;
+ event.sctp_association_event = 1;
+ event.sctp_address_event = 1;
+ event.sctp_send_failure_event = 1;
+ event.sctp_peer_error_event = 1;
+ event.sctp_shutdown_event = 1;
+ event.sctp_partial_delivery_event = 1;
+ event.sctp_adaptation_layer_event = 1;
+ if (setsockopt(fd, IPPROTO_SCTP,
+ SCTP_EVENTS, &event,
+ sizeof(event)) != 0) {
+ printf("Gak, can't set events errno:%d\n",errno);
+ exit(0);
+ }
+ printf("to process\n");
+ process(fd,magic);
+ return(0);
+}
+
diff --git a/src/apps/sctp_darn.c b/src/apps/sctp_darn.c
new file mode 100644
index 0000000..bcfb822
--- /dev/null
+++ b/src/apps/sctp_darn.c
@@ -0,0 +1,2414 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999 Cisco
+ * Copyright (c) 1999, 2000, 2001 Motorola
+ * Copyright (c) 2001 Nokia
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Hui Huang <hui.huang@nokia.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a userspace test application for the SCTP kernel
+ * implementation state machine. It is vaguely inspired by Stevens'
+ * program "sock".
+ *
+ * It has the limited ability to send messages and to listen for messages
+ * sent via SCTP.
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+//#define _GNU_SOURCE
+#include <getopt.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/poll.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <netinet/sctp.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include "sctp_darn.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define GEN_DATA_FIRST 0x21
+#define GEN_DATA_LAST 0x7e
+
+/* Display an IPv4 address in readable format. */
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+/* Display an IPv6 address in readable format. */
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+
+/* These are the global options. */
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+command_t command = COMMAND_NONE;
+struct sockaddr *bindx_add_addrs = NULL;
+int bindx_add_count = 0;
+struct sockaddr *bindx_rem_addrs = NULL;
+int bindx_rem_count = 0;
+struct sockaddr *connectx_addrs = NULL;
+int connectx_count = 0;
+int interactive_mode = 0;
+int poll_skn = 0;
+int nonblocking = 0;
+int opt_space = 0;
+char gen_data = GEN_DATA_FIRST;
+char *inter_outbuf = NULL;
+int inter_outlen = 0;
+int inter_sk = 0;
+int poll_snd_size = 0;
+int use_poll = 0;
+int socket_type = SOCK_SEQPACKET;
+sctp_assoc_t associd = 0;
+int echo = 0;
+char *interface = "eth0";
+int if_index = 0;
+sockaddr_storage_t remote_addr;
+sa_family_t ra_family; /* What family is remote_addr? */
+int ra_len = 0; /* How long is remote_addr? */
+void *ra_raw; /* This is the addr part of remote_addr. */
+int new_connection = 1;
+
+enum inter_cmd_num {
+ INTER_SND = 0,
+ INTER_RCV,
+ INTER_SNDBUF,
+ INTER_RCVBUF,
+ INTER_BINDX_ADD,
+ INTER_BINDX_REM,
+ INTER_SET_PRIM,
+ INTER_SET_PEER_PRIM,
+ INTER_SHUTDOWN,
+ INTER_ABORT,
+ INTER_NODELAY,
+ INTER_MAXSEG,
+ INTER_HEARTBEAT,
+ INTER_GET_STATS
+};
+
+enum shutdown_type {
+ SHUTDOWN_ABORT = 0,
+ SHUTDOWN_SHUTDOWN
+};
+
+struct inter_entry {
+ char *cmd;
+ int cmd_num;
+};
+
+struct inter_entry inter_commands[] = {
+ {"snd", INTER_SND},
+ {"rcv", INTER_RCV},
+ {"sndbuf", INTER_SNDBUF},
+ {"rcvbuf", INTER_RCVBUF},
+ {"bindx-add", INTER_BINDX_ADD},
+ {"bindx-rem", INTER_BINDX_REM},
+ {"primary", INTER_SET_PRIM},
+ {"peer_primary", INTER_SET_PEER_PRIM},
+ {"shutdown", INTER_SHUTDOWN},
+ {"abort", INTER_ABORT},
+ {"nodelay", INTER_NODELAY},
+ {"maxseg", INTER_MAXSEG},
+ {"heartbeat", INTER_HEARTBEAT},
+ {"stats", INTER_GET_STATS},
+ {NULL, -1},
+};
+
+#define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */
+int poll_sks[POLL_SK_MAX]; /* The array for using select(). */
+struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */
+#define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */
+
+
+struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs,
+ int *ret_count) ;
+int build_endpoint(char *argv0, int portnum);
+static int parse_inter_commands(char *, char *, int);
+static void snd_func(char *);
+static void sndbuf_func(char *, int, int, int);
+static void rcvbuf_func(char *, int, int, int);
+static struct sockaddr *get_bindx_addr(char *, int *);
+static int bindx_func(char *, int, struct sockaddr *, int, int, int);
+static int connectx_func(char *, int, struct sockaddr *, int);
+static void primary_func(char *, int, char *, int);
+static void peer_primary_func(char *, int, char *, int);
+static void spp_hb_demand_func(char *, int, char *, int);
+static int nodelay_func(char *, int, int val, int set);
+static int maxseg_func(char *, int, int val, int set);
+static int shutdown_func(char *argv0, int *skp, int shutdown_type);
+static int get_assocstats_func(int, sctp_assoc_t);
+static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id);
+static char * gen_message(int);
+static sctp_assoc_t test_recv_assoc_change(int);
+static sctp_assoc_t test_verify_assoc_change(struct msghdr *);
+void print_addr_buf(void * laddrs, int n_laddrs);
+int print_sockaddr(struct sockaddr *sa_addr);
+
+int
+main(int argc, char *argv[]) {
+ int sk = -1;
+ int error = 0;
+ int i;
+
+ signal(SIGPIPE, SIG_IGN);
+
+ parse_arguments(argc, argv);
+
+ switch(command) {
+ case COMMAND_NONE:
+ fprintf(stderr, "%s: Please specify a command.\n",
+ argv[0]);
+ exit(1);
+ break;
+ case COMMAND_LISTEN:
+ sk = build_endpoint(argv[0], local_port);
+ error = command_listen(argv[0], sk);
+ break;
+ case COMMAND_SEND:
+ sk = build_endpoint(argv[0], local_port);
+ error = command_send(argv[0], &sk);
+ break;
+ case COMMAND_POLL:
+ if (use_poll) {
+ for (i = 0; i < poll_skn; i++) {
+ poll_fds[i].fd = build_endpoint(argv[0],
+ local_port + i);
+ }
+ } else {
+ for (i = 0; i < poll_skn; i++) {
+ poll_sks[i] = build_endpoint(argv[0],
+ local_port + i);
+ }
+ }
+ error = command_poll(argv[0]);
+ break;
+ default:
+ fprintf(stderr, "%s: illegal command %d\n",
+ argv[0], command);
+ exit(1);
+ }
+
+ /* Shut down the link. */
+ if (COMMAND_POLL != command) {
+ close(sk);
+ } else {
+ /* Shutdown all links. */
+ if (use_poll) {
+ for (i = 0; i < poll_skn; i++) {
+ close(poll_fds[i].fd);
+ }
+ } else {
+ for (i = 0; i < poll_skn; i++) {
+ close(poll_sks[i]);
+ }
+ }
+ }
+
+ exit(error);
+}
+
+/********************************************************************
+ * 2nd Level Abstractions
+ ********************************************************************/
+
+void
+parse_arguments(int argc, char *argv[]) {
+ int option_index = 0;
+ int c;
+ struct sockaddr *tmp_addrs = NULL;
+
+ static struct option long_options[] = {
+ {"local", 1, 0, 1},
+ {"local-port", 1, 0, 2},
+ {"remote", 1, 0, 3},
+ {"remote-port", 1, 0, 4},
+ {"listen", 0, 0, 10},
+ {"send", 0, 0, 11},
+ {"bindx-add", 1, 0, 15},
+ {"bindx-rem", 1, 0, 16},
+ {"use-poll", 0, 0, 20},
+ {"echo", 0, 0, 'e'},
+ {"interface", optional_argument, 0, 5,},
+ {"connectx", 1, 0, 17},
+ {0, 0, 0, 0}
+ };
+
+ /* Parse the arguments. */
+ while (1) {
+ c = getopt_long (argc, argv, "B:H:IP:b:h:i:p:lm:nstz:ec:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ printf("option %s", long_options[option_index].name);
+ if (optarg) {
+ printf(" with arg %s", optarg);
+ }
+ printf("\n");
+ break;
+ case 1: /* local host */
+ case 'H':
+ local_host = optarg;
+ break;
+ case 2: /* local port */
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 3: /* remote host */
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 4: /* remote port */
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ case 5: /* interface for sin6_scope_id */
+ if (optarg)
+ interface = optarg;
+ if_index = if_nametoindex(interface);
+ if (!if_index) {
+ printf("Interface %s unknown\n", interface);
+ exit(1);
+ }
+ break;
+ /* COMMANDS */
+ case 10: /* listen */
+ case 'l':
+ if (command) {
+ fprintf(stderr,
+ "%s: pick ONE of listen or send\n",
+ argv[0]);
+ exit(1);
+ } else {
+ command = COMMAND_LISTEN;
+ }
+ break;
+
+ case 11: /* send */
+ case 's':
+ if (command) {
+ fprintf(stderr,
+ "%s: pick ONE of listen or send\n",
+ argv[0]);
+ exit(1);
+ } else {
+ command = COMMAND_SEND;
+ }
+ break;
+
+ case 15: /* bindx_add */
+ case 'B':
+ tmp_addrs =
+ append_addr(optarg, bindx_add_addrs,
+ &bindx_add_count);
+ if (NULL == tmp_addrs) {
+ /* We have no memory, so keep fprintf()
+ * from trying to allocate more.
+ */
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", optarg);
+ exit(2);
+ }
+ bindx_add_addrs = tmp_addrs;
+
+ break;
+
+ case 16: /* bindx_rem */
+ case 'b':
+ tmp_addrs =
+ append_addr(optarg, bindx_rem_addrs,
+ &bindx_rem_count);
+ if (NULL == tmp_addrs) {
+ /* We have no memory, so keep fprintf()
+ * from trying to allocate more.
+ */
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", optarg);
+ exit(2);
+ }
+ bindx_rem_addrs = tmp_addrs;
+ break;
+ case 17: /* connectx */
+ case 'c':
+ tmp_addrs =
+ append_addr(optarg, connectx_addrs,
+ &connectx_count);
+ if (NULL == tmp_addrs) {
+ /* We have no memory, so keep fprintf()
+ * from trying to allocate more.
+ */
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", optarg);
+ exit(2);
+ }
+ connectx_addrs = tmp_addrs;
+ break;
+ case 20: /* use-poll */
+ use_poll = 1;
+ break;
+ case 'I':
+ interactive_mode = 1;
+ break;
+ case 'i':
+ command = COMMAND_POLL;
+ poll_skn = atoi(optarg);
+ if (poll_skn <= 0 || poll_skn > POLL_SK_MAX) {
+ fprintf(stderr, "Too many sockets for ");
+ fprintf(stderr, "for polling\n");
+ exit(2);
+ }
+ break;
+ case 'm':
+ opt_space = atoi(optarg);
+ break;
+ case 'n':
+ nonblocking = 1;
+ break;
+ case 't':
+ socket_type = SOCK_STREAM;
+ break;
+ case 'z':
+ poll_snd_size = atoi(optarg);
+ if (poll_snd_size <= 0) {
+ fprintf(stderr, "Bad message size.\n");
+ exit(2);
+ }
+ break;
+ case 'e':
+ echo = 1;
+ break;
+ case '?':
+ usage(argv[0]);
+ exit(1);
+
+ default:
+ printf ("%s: unrecognized option 0%c\n",
+ argv[0], c);
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (optind < argc)
+ {
+ fprintf(stderr, "%s: non-option arguments are illegal: ",
+ argv[0]);
+ while (optind < argc)
+ fprintf(stderr, "%s ", argv[optind++]);
+ fprintf (stderr, "\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+
+ if (NULL == local_host) {
+ fprintf(stderr, "%s: You MUST provide a local host.\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (command == COMMAND_SEND && NULL == remote_host
+ && connectx_count == 0) {
+ fprintf(stderr, "%s: You MUST provide a remote host for sending.\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (remote_host != NULL && connectx_count != 0) {
+ fprintf(stderr, "%s: You can not provide both -h and -c options.\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+} /* parse_arguments() */
+
+/* Set up the local endpoint. */
+int
+build_endpoint(char *argv0, int portnum)
+{
+ int retval;
+ struct hostent *hst;
+ sockaddr_storage_t local_addr;
+ sa_family_t la_family; /* What family is local_addr? */
+ int la_len; /* How long is local_addr? */
+ void *la_raw; /* This is the addr part of local_addr. */
+ int error;
+ struct sctp_event_subscribe subscribe;
+
+ /* Get the transport address for the local host name. */
+ hst = gethostbyname(local_host);
+ if (hst == NULL) {
+ hst = gethostbyname2(local_host, AF_INET6);
+ }
+
+ if (hst == NULL || hst->h_length < 1) {
+ fprintf(stderr, "%s: bad hostname: %s\n", argv0, local_host);
+ exit(1);
+ }
+
+ la_family = hst->h_addrtype;
+ switch (la_family) {
+ case AF_INET:
+ la_len = sizeof(local_addr.v4);
+ la_raw = &local_addr.v4.sin_addr;
+ local_addr.v4.sin_port = htons(portnum);
+ local_addr.v4.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ la_len = sizeof(local_addr.v6);
+ la_raw = &local_addr.v6.sin6_addr;
+ local_addr.v6.sin6_port = htons(portnum);
+ local_addr.v6.sin6_family = AF_INET6;
+ local_addr.v6.sin6_scope_id = if_index;
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+ memcpy(la_raw, hst->h_addr_list[0], hst->h_length);
+
+ /* Create the local endpoint. */
+ retval = socket(la_family, socket_type, IPPROTO_SCTP);
+ if (retval < 0) {
+ fprintf(stderr, "%s: failed to create socket: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ if (SOCK_SEQPACKET == socket_type) {
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ error = setsockopt(retval, SOL_SCTP, SCTP_EVENTS,
+ (char *)&subscribe, sizeof(subscribe));
+ if (error) {
+ fprintf(stderr, "SCTP_EVENTS: error: %d\n", error);
+ exit(1);
+ }
+ }
+
+ /* Bind this socket to the test port. */
+ error = bind(retval, &local_addr.sa, la_len);
+ if (error != 0) {
+ fprintf(stderr, "%s: can not bind to %s:%d: %s.\n",
+ argv0, local_host, portnum,
+ strerror(errno));
+ exit(1);
+ }
+
+ /* Do we need to do bindx() to add any additional addresses? */
+ if (bindx_add_addrs) {
+ if (0 != bindx_func(argv0, retval, bindx_add_addrs,
+ bindx_add_count, SCTP_BINDX_ADD_ADDR, portnum)) {
+ fprintf(stderr, "bindx_func (add) failed.\n");
+ exit(1);
+ }
+ } /* if (bindx_add_addrs) */
+
+ /* Do we need to do bindx() to remove any bound addresses? */
+ if (bindx_rem_addrs) {
+ if (0 != bindx_func(argv0, retval, bindx_rem_addrs,
+ bindx_rem_count, SCTP_BINDX_REM_ADDR, portnum)) {
+ fprintf(stderr, "bindx_func (remove) failed.\n");
+ exit(1);
+ }
+ } /* if (bindx_rem_addrs) */
+
+ /* Do we want to run in the non-blocking mode? */
+ if (nonblocking) {
+ error = fcntl(retval, F_SETFL, O_NONBLOCK);
+ if (error != 0) {
+ fprintf(stderr, "%s: error fcntl: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+ }
+
+ if (opt_space) {
+ sndbuf_func(argv0, retval, opt_space, 1);
+ rcvbuf_func(argv0, retval, opt_space, 1);
+ }
+
+ return retval;
+
+} /* build_endpoint() */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+ struct sctp_initmsg init;
+ struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+
+/* Listen on the socket, printing out anything that arrives. */
+int
+command_listen(char *argv0, int sk)
+{
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ struct msghdr inmessage;
+ sockaddr_storage_t msgname;
+ char message[REALLY_BIG];
+ int done = 0;
+ int error;
+ int c;
+ int recvsk = 0;
+
+ /* Mark sk as being able to accept new associations */
+ error = listen(sk, 5);
+ if (error != 0) {
+ printf("\n\n\t\tlisten Failure: %s.\n\n\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ if (nonblocking) {
+ if (!interactive_mode) {
+ printf("Use -I for interactive mode with");
+ printf(" -n nonblocking\n");
+ exit(1);
+ }
+ }
+
+ /* Initialize the global value for interactive mode functions. */
+ if (interactive_mode) {
+ inter_sk = sk;
+ }
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ printf("%s: Can't allocate memory.\n", argv0);
+ exit(1);
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof(msgname);
+
+ printf("%s listening...\n", argv0);
+ /* Get the messages sent */
+ done = 0;
+ while (!done) {
+ if (interactive_mode) {
+ /* Read from the user. */
+ if (remote_host) {
+ printf("%s:%d-%s:%d Interactive mode> ",
+ local_host, local_port, remote_host,
+ remote_port);
+ } else {
+ printf("%s:%d-", local_host, local_port);
+ if (associd) {
+ print_sockaddr(&remote_addr.sa);
+ } else {
+ printf("?:%d", remote_port);
+ }
+ printf(" Interactive mode> ");
+ }
+ fflush(stdout);
+ if (NULL == fgets(message, REALLY_BIG, stdin)) {
+ done = 1;
+ continue;
+ }
+
+ if (0 <= (c = parse_inter_commands(argv0, message,
+ 0))) {
+ if (INTER_RCV != c) {
+ continue;
+ }
+ } else {
+ continue;
+ }
+ }
+
+ if (socket_type == SOCK_STREAM) {
+ socklen_t len = 0;
+
+ if (!recvsk) {
+ if ((recvsk = accept(sk, NULL, &len)) < 0) {
+ fprintf(stderr, "%s: error: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+ }
+
+ } else {
+ recvsk = sk;
+ }
+
+ error = recvmsg(recvsk, &inmessage, MSG_WAITALL);
+ if (error < 0) {
+ if (nonblocking && (EAGAIN == errno)) {
+ error = 0;
+ continue;
+ }
+
+ if (socket_type == SOCK_STREAM) {
+ if (ENOTCONN != errno)
+ break;
+ printf("No association is present now!!\n");
+ close(recvsk);
+ recvsk = 0;
+ continue;
+ }
+ break;
+ }
+
+ /* Update the associd when a notification is received on a
+ * UDP-style socket.
+ */
+ if (inmessage.msg_flags & MSG_NOTIFICATION)
+ associd = test_verify_assoc_change(&inmessage);
+
+ if (echo) {
+ if( !(MSG_NOTIFICATION & inmessage.msg_flags)) {
+ if (sendto(recvsk, inmessage.msg_iov->iov_base,
+ error, 0,
+ (struct sockaddr *)&msgname,
+ sizeof(msgname)) == -1) {
+ fprintf(stderr, "%s: error: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+ }
+ }
+
+ test_print_message(sk, &inmessage, error);
+
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof(msgname);
+ iov.iov_len = REALLY_BIG;
+
+ /* Verify that the association is no longer present. */
+ if (0 != test_sk_for_assoc(recvsk, associd)) {
+ printf("No association is present now!!\n");
+ if (socket_type == SOCK_STREAM) {
+ close(recvsk);
+ recvsk = 0;
+ }
+ }
+ }
+
+ if (error < 0) {
+ fprintf(stderr, "%s: error: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ return error;
+
+} /* command_listen() */
+
+/* Read lines from stdin and send them to the socket. */
+int
+command_send(char *argv0, int *skp)
+{
+ struct msghdr outmsg;
+ struct iovec iov;
+ int done = 0;
+ char message[REALLY_BIG];
+ struct hostent *hst;
+ int c;
+ struct sockaddr *addrs;
+ int msglen;
+ int error = 0;
+ int sk = *skp;
+
+ /* Set up the destination. */
+ if (remote_host != NULL) {
+ hst = gethostbyname(remote_host);
+ if (hst == NULL) {
+ hst = gethostbyname2(remote_host, AF_INET6);
+ }
+
+ if (hst == NULL || hst->h_length < 1) {
+ fprintf(stderr, "%s: bad hostname: %s\n",
+ argv0, remote_host);
+ exit(1);
+ }
+
+ ra_family = hst->h_addrtype;
+ switch (ra_family) {
+ case AF_INET:
+ ra_len = sizeof(remote_addr.v4);
+ ra_raw = &remote_addr.v4.sin_addr;
+ remote_addr.v4.sin_port = htons(remote_port);
+ remote_addr.v4.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ ra_len = sizeof(remote_addr.v6);
+ ra_raw = &remote_addr.v6.sin6_addr;
+ remote_addr.v6.sin6_port = htons(remote_port);
+ remote_addr.v6.sin6_family = AF_INET6;
+ remote_addr.v6.sin6_scope_id = if_index;
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+ memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+ }
+
+ /* Initialize the global value for interactive mode functions. */
+ if (interactive_mode) {
+ inter_sk = sk;
+ }
+
+ printf("%s ready to send...\n", argv0);
+ while (!done) {
+ /* Read from the user. */
+ if (remote_host) {
+ if (interactive_mode) {
+ printf("%s:%d-%s:%d Interactive mode> ",
+ local_host, local_port, remote_host,
+ remote_port);
+ } else {
+ printf("%s:%d-%s:%d> ",
+ local_host, local_port,
+ remote_host, remote_port);
+ }
+ } else {
+ printf("%s:%d-", local_host, local_port);
+ if (associd) {
+ print_sockaddr(&remote_addr.sa);
+ } else {
+ printf("XXXXXX:%d", remote_port);
+ }
+ if (interactive_mode) {
+ printf(" Interactive mode> ");
+ } else {
+ printf("> ");
+ }
+ }
+ fflush(stdout);
+ if (NULL == fgets(message, REALLY_BIG, stdin)) {
+ done = 1;
+ continue;
+ }
+
+ if (interactive_mode) {
+ /* This is the send only agent. */
+ if (0 <= (c = parse_inter_commands(argv0, message,
+ 1))) {
+ if (INTER_SND == c) {
+ iov.iov_base = inter_outbuf;
+ msglen = inter_outlen;
+ iov.iov_len = msglen;
+
+ } else {
+ continue;
+ }
+
+ } else {
+ continue;
+ }
+ } else {
+ /* Send to our neighbor. */
+ msglen = strlen(message) + 1;
+ iov.iov_len = msglen;
+ }
+
+ /* For a UDP-style socket, verify if an existing association
+ * has gone. If so, receive the pending SCTP_ASSOC_CHANGE
+ * notification.
+ */
+ if ((SOCK_SEQPACKET == socket_type) && associd &&
+ (0 != test_sk_for_assoc(sk, associd))) {
+ associd = test_recv_assoc_change(sk);
+ printf("Old association gone, Starting a new one!\n");
+ new_connection = 1;
+ }
+
+ if (new_connection && connectx_count != 0) {
+ /* Do a sctp_connectx() to establish a connection. */
+ error = connectx_func(argv0, sk, connectx_addrs,
+ connectx_count);
+ if (0 != error) {
+ if (error == -2) {
+ printf("Connection refused\n");
+ if (SOCK_SEQPACKET == socket_type) {
+ associd = test_recv_assoc_change(sk);
+ }
+ continue;
+ }
+ fprintf(stderr, "connectx failed.\n");
+ exit(1);
+ }
+ if (SOCK_SEQPACKET == socket_type) {
+ associd = test_recv_assoc_change(sk);
+ } else {
+ associd = 1;
+ }
+ int rc = sctp_getpaddrs(sk, associd, &addrs);
+ if (0 >= rc) {
+ if (rc == 0) {
+ fprintf(stderr, "sctp_getpaddrs failed, no peers.\n");
+ } else {
+ fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno);
+ }
+ exit(1);
+ }
+ printf("New connection, peer addresses\n");
+ print_addr_buf(addrs, rc);
+ ra_family = addrs[0].sa_family;
+ switch (ra_family) {
+ case AF_INET:
+ ra_len = sizeof(remote_addr.v4);
+ break;
+ case AF_INET6:
+ ra_len = sizeof(remote_addr.v6);
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ }
+ memcpy(&remote_addr, &addrs[0], ra_len);
+ sctp_freepaddrs(addrs);
+ new_connection = 0;
+ }
+
+ do {
+ if (SOCK_SEQPACKET == socket_type ||
+ (connectx_count == 0 && new_connection)) {
+ /* Initialize the message struct we use to pass
+ * messages to the remote socket.
+ */
+ if (!interactive_mode) {
+ iov.iov_base = message;
+ iov.iov_len = msglen;
+ }
+ outmsg.msg_iov = &iov;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = NULL;
+ outmsg.msg_controllen = 0;
+ outmsg.msg_name = &remote_addr;
+ outmsg.msg_namelen = ra_len;
+ outmsg.msg_flags = 0;
+
+ error = sendmsg(sk, &outmsg, 0);
+ } else {
+ error = send(sk, message, msglen, 0);
+ if (error == -1 && errno == EPIPE) {
+ error = close(sk);
+ if (error != 0) {
+ fprintf(stderr, "close failed %s\n", strerror(errno));
+ exit(1);
+ }
+ *skp = sk = build_endpoint(argv0, local_port);
+ break;
+ }
+ }
+
+ if (error != msglen) {
+ fprintf(stderr, "%s: error: %s.\n",
+ argv0, strerror(errno));
+ if (nonblocking && EAGAIN == errno) {
+ if (interactive_mode) {
+ break;
+ }
+ continue;
+ }
+ exit(1);
+ } else {
+ break;
+ }
+ } while (error != msglen);
+
+ /* If this is the first message sent over a UDP-style socket,
+ * get the associd from the SCTP_ASSOC_CHANGE notification.
+ */
+ if ((SOCK_SEQPACKET == socket_type) && (0 == associd))
+ associd = test_recv_assoc_change(sk);
+
+ /* Verify there is no association. */
+ if (0 != test_sk_for_assoc(sk, associd)) {
+ printf("No association is present now!!\n");
+ new_connection = 1;
+ } else {
+ if (new_connection) {
+ int rc = sctp_getpaddrs(sk, associd, &addrs);
+ if (0 >= rc) {
+ if (rc == 0) {
+ fprintf(stderr, "sctp_getpaddrs failed, no peers.\n");
+ } else {
+ fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno);
+ }
+ exit(1);
+ }
+ printf("New connection, peer addresses\n");
+ print_addr_buf(addrs, rc);
+ sctp_freepaddrs(addrs);
+ new_connection = 0;
+ }
+ }
+
+ /* Clean up. */
+ if (interactive_mode) {
+ free(inter_outbuf);
+ inter_outbuf = NULL;
+ }
+ } /* while(!done) */
+
+ return error;
+
+} /* command_send() */
+
+/* Listen on the array of sockets, printing out anything that arrives. */
+int
+command_poll(char *argv0)
+{
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ struct msghdr inmessage;
+ int done = 0;
+ int error = 0;
+ int max_fd, i, ret;
+ int size;
+ fd_set *ibitsp = NULL;
+ fd_set *obitsp = NULL;
+ fd_set *xbitsp = NULL;
+
+ struct msghdr outmsg;
+ struct hostent *hst;
+ int msglen;
+ int temp_fd, temp_set;
+
+
+
+ /* If a remote host is specified, initialize the destination. */
+ if (remote_host) {
+ /* Set up the destination. */
+ hst = gethostbyname(remote_host);
+ if (hst == NULL) {
+ hst = gethostbyname2(remote_host, AF_INET6);
+ }
+
+ if (hst == NULL || hst->h_length < 1) {
+ fprintf(stderr, "%s: bad hostname: %s\n",
+ argv0, remote_host);
+ exit(1);
+ }
+
+ ra_family = hst->h_addrtype;
+ switch (ra_family) {
+ case AF_INET:
+ ra_len = sizeof(remote_addr.v4);
+ ra_raw = &remote_addr.v4.sin_addr;
+ remote_addr.v4.sin_port = htons(remote_port);
+ remote_addr.v4.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ ra_len = sizeof(remote_addr.v6);
+ ra_raw = &remote_addr.v6.sin6_addr;
+ remote_addr.v6.sin6_port = htons(remote_port);
+ remote_addr.v6.sin6_family = AF_INET6;
+ remote_addr.v6.sin6_scope_id = if_index;
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+ memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+
+ /* Initialize the message struct we use to pass messages to
+ * the remote socket.
+ */
+ outmsg.msg_iov = &iov;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = NULL;
+ outmsg.msg_controllen = 0;
+ outmsg.msg_name = &remote_addr;
+ outmsg.msg_namelen = ra_len;
+ outmsg.msg_flags = 0;
+ }
+
+
+ max_fd = -1;
+
+ /* Set all of the sockets to be ready for listening. */
+ if (use_poll) {
+ for (i = 0; i < poll_skn; i++) {
+ error = listen(poll_fds[i].fd, 1);
+ if (error != 0) {
+ printf("%s: Listen failed on socket number ",
+ argv0);
+ printf("%d: %s.\n", i, strerror(errno));
+ exit(1);
+ }
+ }
+ printf("%s listening...\n", argv0);
+ } else {
+ for (i = 0; i < poll_skn; i++) {
+ error = listen(poll_sks[i], 1);
+ if (error != 0) {
+ printf("%s: Listen failed on socket number ",
+ argv0);
+ printf("%d: %s.\n", i, strerror(errno));
+ exit(1);
+ }
+ if (poll_sks[i] > max_fd) {
+ max_fd = poll_sks[i];
+ }
+ }
+ printf("%s listening...\n", argv0);
+
+ size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask);
+ if ((ibitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("%s: Can't allocate memory.\n", argv0);
+ exit(1);
+ }
+ if ((obitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("%s: Can't allocate memory.\n", argv0);
+ exit(1);
+ }
+ if ((xbitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("%s: Can't allocate memory.\n", argv0);
+ exit(1);
+ }
+ memset(ibitsp, 0, size);
+ memset(obitsp, 0, size);
+ memset(xbitsp, 0, size);
+ }
+
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ printf("%s: Can't allocate memory.\n", argv0);
+ exit(1);
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+
+ done = 0;
+ /* Set the default send message size. */
+ if (!poll_snd_size) {
+ poll_snd_size = POLL_SND_SIZE;
+ }
+
+ while (!done) {
+
+ if (use_poll) {
+ for (i = 0; i < poll_skn; i++) {
+ poll_fds[i].events = POLLIN;
+ }
+ if (remote_host) {
+ /* Poll output on the first socket. */
+ poll_fds[0].events |= POLLOUT;
+ }
+
+ if ((ret = poll(poll_fds, poll_skn, -1))) {
+ if (ret == -1) {
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < poll_skn; i++) {
+ FD_SET(poll_sks[i], ibitsp);
+ FD_SET(poll_sks[i], xbitsp);
+ }
+ if (remote_host) {
+ /* Only select output on the first socket. */
+ FD_SET(poll_sks[0], obitsp);
+ }
+
+
+ if ((ret = select(max_fd + 1, ibitsp, obitsp, xbitsp,
+ (struct timeval *)0)) < 0) {
+ if (ret == -1) {
+ break;
+ }
+ }
+
+ }
+
+ if (remote_host) {
+ if (use_poll) {
+ temp_set = poll_fds[0].revents & POLLOUT;
+ temp_fd = poll_fds[0].fd;
+ } else {
+ temp_set = FD_ISSET(poll_sks[0], obitsp);
+ temp_fd = poll_sks[0];
+ }
+
+ if (temp_set) {
+ inter_outbuf = gen_message(poll_snd_size);
+ if (!inter_outbuf) {
+ fprintf(stderr,
+ "Cannot allocate out message.\n");
+ exit(1);
+ }
+ iov.iov_base = inter_outbuf;
+ msglen = poll_snd_size;
+ iov.iov_len = msglen;
+
+ error = sendmsg(temp_fd, &outmsg, 0);
+ fprintf(stderr,
+ "sent a message, msglen = %d\n",
+ msglen);
+
+ if (error != msglen) {
+ fprintf(stderr, "%s: error: %s.\n",
+ argv0, strerror(errno));
+ if ((!nonblocking) ||
+ (EAGAIN != errno)) {
+ exit(1);
+ }
+ }
+
+ /* Clean up. */
+ free(inter_outbuf);
+ inter_outbuf = NULL;
+ }
+
+ } /* while(!done) */
+
+ for (i = 0; !done && (i < poll_skn); i++) {
+ if (use_poll) {
+ temp_set = poll_fds[i].revents & POLLIN;
+ temp_fd = poll_fds[i].fd;
+ } else {
+ temp_set = FD_ISSET(poll_sks[i], ibitsp);
+ temp_fd = poll_sks[i];
+ }
+ if (temp_set) {
+ error = recvmsg(temp_fd, &inmessage,
+ MSG_WAITALL);
+ if (error < 0) {
+ if ((EAGAIN == errno)) {
+ error = 0;
+ continue;
+ }
+ else {
+ fprintf(stderr,
+ "%s: error: %s.\n",
+ argv0,
+ strerror(errno));
+ exit(1);
+ }
+ }
+ test_print_message(temp_fd, &inmessage, error);
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ iov.iov_len = REALLY_BIG;
+ }
+
+ /* Update the associd when a notification is received
+ * on a UDP-style socket.
+ */
+ if (inmessage.msg_flags & MSG_NOTIFICATION)
+ associd = test_verify_assoc_change(&inmessage);
+
+ /* Verify there is no association. */
+ if (0 != test_sk_for_assoc(poll_sks[i], associd)) {
+ printf("No association is present in sk "
+ "No.%d now!!\n",i);
+ }
+ }
+
+ }
+
+ if (!use_poll) {
+ free(ibitsp);
+ free(obitsp);
+ free(xbitsp);
+ }
+
+ return error;
+
+} /* command_poll() */
+
+/********************************************************************
+ * 3rd Level Abstractions
+ ********************************************************************/
+
+#define FPS(arg) fprintf(stderr, arg)
+
+void
+usage(char *argv0)
+{
+ /*
+ * The bindx options, --bindx-add and --bindx-rem, are added to
+ *
+ * 1. provide first testcases for the new bindx system call
+ *
+ * 2. continue to grow sctp_darn with more functions and
+ * features so it will be equivalent to the "sock" tool for
+ * TCP as for SCTP.
+ *
+ * FIXME -
+ *
+ * It is not very effective to use these two options in the
+ * current command line mode of sctp_darn. For example, the
+ * --bindx-rem option can only be used in conjunction with the
+ * --bindx-add simply to test the function in the kernel
+ * path. Ideally, bindx needs to be tested by a tool which
+ * provides an interactive mode for users to change parameters
+ * and configuration dynamically with existing endpoints and
+ * associations.
+ */
+ fprintf(stderr, "Usage: %s -H <localhost> -P <localport> "
+ "[-h <remotehost>] [-p <remoteport>] -l|s\n"
+ " -H, --local\t\tspecify one of the local addresses,\n"
+ " -P, --local-port\tspecify the port number for local addresses,\n"
+ " -h, --remote\t\tspecify the peer address,\n"
+ " -p, --remote-port\tspecify the port number for the peer address,\n"
+ " -l, --listen\t\tprint messages received from the peer,\n"
+ " -s, --send\t\tsend messages to the peer,\n"
+ " -B, --bindx-add"
+ "\tadd the specified address(es) as additional bind\n"
+ "\t\t\taddresses to the local socket. Multiple addresses can\n"
+ "\t\t\tbe specified by using this argument multiple times.\n"
+ "\t\t\tFor example, '-B 10.0.0.1 -B 20.0.0.2'.\n"
+ " -b, --bindx-rem"
+ "\tremove the specified address(es) from the bind\n"
+ "\t\t\taddresses of the local socket. Multiple addresses can\n"
+ "\t\t\tbe specified by using this argument multiple times.\n"
+ "\t\t\tFor example, '-b 10.0.0.1 -b 20.0.0.2'.\n"
+ " -c, --connectx"
+ "\t\tuse the specified address(es) for connection to the\n"
+ "\t\t\tpeer socket. Multiple addresses can be specified by\n"
+ "\t\t\tusing this argument multiple times.\n"
+ "\t\t\tFor example, '-c 10.0.0.1 -c 20.0.0.2'.\n"
+ "\t\t\tThis option is incompatible with the -h option.\n"
+ " -I\t\t\tuse the interactive mode.\n"
+ " -i\t\t\tsetup the specified number of endpoints by using the\n"
+ "\t\t\tspecified local host (-H) and local port (-P). The port\n"
+ "\t\t\tnumber will be incremented by one for each additional\n"
+ "\t\t\tendpoint. All of these endpoints will be listening.\n"
+ "\t\t\tIf a remote host (-h) and a remote port are also\n"
+ "\t\t\tspecified, the first endpoint will start sending fixed\n"
+ "\t\t\tsized messages to the remote host.\n"
+ " -m\t\t\tspecify the sockopt sndbuf/rcvbuf size.\n"
+ " -n\t\t\tset the socket(s) to be in the non-blocking mode.\n"
+ "\t\t\tcollect messages from stdin and deliver them to the\n"
+ "\t\t\tpeer,\n"
+ "--use-poll\t\tuse system call poll() for polling among the\n"
+ "\t\t\tnumber of endpoints specified by the -i option. Without\n"
+ "\t\t\tthis option, select() would be used as default.\n"
+ " -t\t\t\tuse SOCK_STREAM tcp-style sockets.\n"
+ " -z\t\t\tspecify the message size to be sent. The default\n"
+ "\t\t\tmessage size generated would be 16K.\n"
+ " --interface=\"ifname\"\tselect interface for sin6_scope_id.\n",
+ argv0);
+}
+
+
+/* This function checks messages to see if they are of type 'event'
+ * and if they are well-formed.
+ */
+int
+user_test_check_message(struct msghdr *msg,
+ int controllen,
+ sctp_cmsg_t event)
+{
+
+
+ if (msg->msg_controllen != controllen) {
+ fprintf(stderr,
+ "Got control structure of length %zu, not %d\n",
+ msg->msg_controllen, controllen);
+ exit(1);
+ }
+ if (controllen > 0 && event != CMSG_FIRSTHDR(msg)->cmsg_type) {
+ fprintf(stderr, "Wrong kind of event: %d, not %d\n",
+ CMSG_FIRSTHDR(msg)->cmsg_type, event);
+ exit(1);
+ }
+
+ return 1;
+
+} /* user_test_check_message() */
+
+/* Add another address represented as the string 'parm' to the list
+ * addrs. The argument count is the number of addrs on input and is
+ * adjusted for output.
+ */
+struct sockaddr *
+append_addr(const char *parm, struct sockaddr *addrs, int *ret_count)
+{
+ struct sockaddr *new_addrs = NULL;
+ void *aptr;
+ struct sockaddr *sa_addr;
+ struct sockaddr_in *b4ap;
+ struct sockaddr_in6 *b6ap;
+ struct hostent *hst4 = NULL;
+ struct hostent *hst6 = NULL;
+ int i4 = 0;
+ int i6 = 0;
+ int j;
+ int orig_count = *ret_count;
+ int count = orig_count;
+
+
+ if (!parm)
+ return NULL;
+ /* Get the entries for this host. */
+ hst4 = gethostbyname(parm);
+ hst6 = gethostbyname2(parm, AF_INET6);
+
+ if ((NULL == hst4 || hst4->h_length < 1)
+ && (NULL == hst6 || hst6->h_length < 1)) {
+ fprintf(stderr, "bad hostname: %s\n", parm);
+ goto finally;
+ }
+
+
+ /* Figure out the number of addresses. */
+ if (NULL != hst4) {
+ for (i4 = 0; NULL != hst4->h_addr_list[i4]; ++i4) {
+ count++;
+ }
+ }
+ if (NULL != hst6) {
+ for (i6 = 0; NULL != hst6->h_addr_list[i6]; ++i6) {
+ count++;
+ }
+ }
+
+ /* Expand memory for the new addresses. Assume all the addresses
+ * are v6 addresses.
+ */
+ new_addrs = (struct sockaddr *)
+ realloc(addrs, sizeof(struct sockaddr_in6) * count);
+
+ if (NULL == new_addrs) {
+ count = *ret_count;
+ goto finally;
+ }
+
+ /* Skip the existing addresses. */
+ aptr = new_addrs;
+ for (j = 0; j < orig_count; j++) {
+ sa_addr = (struct sockaddr *)aptr;
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ count = orig_count;
+ goto finally;
+ }
+ }
+
+ /* Put the new addresses away. */
+ if (NULL != hst4) {
+ for (j = 0; j < i4; ++j) {
+ b4ap = (struct sockaddr_in *)aptr;
+ memset(b4ap, 0x00, sizeof(*b4ap));
+ b4ap->sin_family = AF_INET;
+ b4ap->sin_port = htons(local_port);
+ bcopy(hst4->h_addr_list[j], &b4ap->sin_addr,
+ hst4->h_length);
+
+ aptr += sizeof(struct sockaddr_in);
+ } /* for (loop through the new v4 addresses) */
+ }
+
+ if (NULL != hst6) {
+ for (j = 0; j < i6; ++j) {
+ b6ap = (struct sockaddr_in6 *)aptr;
+ memset(b6ap, 0x00, sizeof(*b6ap));
+ b6ap->sin6_family = AF_INET6;
+ b6ap->sin6_port = htons(local_port);
+ b6ap->sin6_scope_id = if_index;
+ bcopy(hst6->h_addr_list[j], &b6ap->sin6_addr,
+ hst6->h_length);
+
+ aptr += sizeof(struct sockaddr_in6);
+ } /* for (loop through the new v6 addresses) */
+ }
+
+ finally:
+
+ *ret_count = count;
+
+ return new_addrs;
+
+} /* append_addr() */
+
+static int
+parse_inter_commands(char *argv0, char *input, int snd_only)
+{
+ int i;
+ char *p;
+ int len;
+ int set = 0;
+ int val;
+ struct sockaddr *tmp_addrs = NULL;
+
+
+ p = input;
+ if (*p == '?' || *p == '\n') {
+ printf("Interactive commands:\n");
+ printf("snd=<int> - Do a sendmsg with the specified");
+ printf(" length.\n");
+ printf("rcv=<int> - Do a recvmsg.");
+ printf("The length is ignored for now.\n");
+ printf("bindx-add=<addr> - Add a local address");
+ printf(" with bindx. \n");
+ printf("bindx-rem=<addr> - Remove a local address");
+ printf(" with bindx. \n");
+ printf("rcvbuf=<int> - Get/Set receive buffer size\n");
+ printf("sndbuf=<int> - Get/Set send buffer size.\n");
+ printf("primary=<addr> - Get/Set association's primary\n");
+ printf("peer_primary=addr- Set association's peer_primary\n");
+ printf("heartbeat=<addr> - Request a user initiated heartbeat\n");
+ printf("maxseg=<int> - Get/Set Maximum fragment size.\n");
+ printf("nodelay=<0|1> - Get/Set NODELAY option.\n");
+ printf("shutdown - Shutdown the association.\n");
+ printf("abort - Abort the association.\n");
+ printf("stats - Print GET_ASSOC_STATS (if available in kernel).\n");
+ printf("? - Help. Display this message.\n");
+ return -1;
+ }
+
+ for (i = 0; i < REALLY_BIG; i++) {
+ if (('=' == *p) ||
+ ('?' == *p) ||
+ ('\n' == *p)) {
+ if ('=' == *p) {
+ set = 1;
+ }
+ *p++ = '\0';
+ break;
+ }
+ p++;
+ }
+ if (i >= REALLY_BIG) {
+ printf("Invalid input.\n");
+ return -1;
+ }
+
+ i = 0;
+ while (NULL != inter_commands[i].cmd) {
+ if (!strcmp(input, inter_commands[i].cmd)) {
+ switch (i) {
+ case INTER_SND:
+ if (snd_only) {
+ if (*p < '0' || *p > '9') {
+ goto err_input;
+ }
+ snd_func(p);
+ } else {
+ goto err_input;
+ }
+ break;
+ case INTER_RCV:
+ if (snd_only) {
+ goto err_input;
+ }
+ break;
+ case INTER_SNDBUF:
+ if (set) {
+ if (*p < '0' || *p > '9') {
+ goto err_input;
+ }
+ }
+ len = (set) ? atoi(p) : 0;
+ sndbuf_func(argv0, inter_sk, len, set);
+ break;
+ case INTER_RCVBUF:
+ if (set) {
+ if (*p < '0' || *p > '9') {
+ goto err_input;
+ }
+ }
+ len = (set) ? atoi(p) : 0;
+ rcvbuf_func(argv0, inter_sk, len, set);
+ break;
+ case INTER_BINDX_ADD:
+ tmp_addrs = get_bindx_addr(p, &len);
+ bindx_func(argv0, inter_sk, tmp_addrs, len,
+ SCTP_BINDX_ADD_ADDR, local_port);
+ free(tmp_addrs);
+ break;
+ case INTER_BINDX_REM:
+ tmp_addrs = get_bindx_addr(p, &len);
+ bindx_func(argv0, inter_sk, tmp_addrs, len,
+ SCTP_BINDX_REM_ADDR, local_port);
+ free(tmp_addrs);
+ break;
+ case INTER_SET_PRIM:
+ primary_func(argv0, inter_sk, p, set);
+ break;
+ case INTER_SET_PEER_PRIM:
+ peer_primary_func(argv0, inter_sk, p, set);
+ break;
+ case INTER_HEARTBEAT:
+ spp_hb_demand_func(argv0, inter_sk, p, set);
+ break;
+ case INTER_SHUTDOWN:
+ shutdown_func(argv0, &inter_sk, SHUTDOWN_SHUTDOWN);
+ break;
+ case INTER_ABORT:
+ shutdown_func(argv0, &inter_sk, SHUTDOWN_ABORT);
+ break;
+ case INTER_NODELAY:
+ if (set) {
+ if (*p < '0' || *p > '9') {
+ goto err_input;
+ }
+ }
+ val = (set) ? atoi(p) : 0;
+ nodelay_func(argv0, inter_sk, val, set);
+ break;
+ case INTER_MAXSEG:
+ if (set) {
+ if (*p < '0' || *p > '9') {
+ goto err_input;
+ }
+ }
+ val = (set) ? atoi(p) : 0;
+ maxseg_func(argv0, inter_sk, val, set);
+ break;
+ case INTER_GET_STATS:
+ get_assocstats_func(inter_sk, associd);
+ break;
+ default:
+ goto err_input;
+ break;
+ }
+
+ return i;
+ }
+ i++;
+ }
+
+err_input:
+ printf("Invalid input.\n");
+ return -1;
+
+} /* parse_inter_commands() */
+
+static char *
+gen_message(int len)
+{
+
+ char *buf;
+ char *p;
+ int i;
+
+ buf = malloc(len);
+
+ if (NULL != buf) {
+ for (i = 0, p = buf; i < len; i++, p++) {
+ if (gen_data > GEN_DATA_LAST) {
+ gen_data = GEN_DATA_FIRST;
+ }
+ *p = gen_data++;
+ }
+ }
+
+ return(buf);
+
+} /* gen_message() */
+
+static void
+snd_func(char *input)
+{
+
+ int len;
+
+ len = atoi(input);
+ if (!(inter_outbuf = gen_message(len))) {
+ fprintf(stderr, "Cannot allocate out message.\n");
+ exit(1);
+ }
+ inter_outlen = len;
+
+} /* snd_func() */
+
+static void
+sndbuf_func(char *argv0, int sk, int len, int set)
+{
+ int error;
+ socklen_t optlen;
+
+ if (set) {
+ error = setsockopt(sk, SOL_SOCKET, SO_SNDBUF,
+ (char *)&len, sizeof(len));
+ } else {
+ optlen = sizeof(len);
+ error = getsockopt(sk, SOL_SOCKET, SO_SNDBUF,
+ (char *)&len, &optlen);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: Error setting/getting sndbuf: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ if (!set) {
+ printf("sndbuf is %d.\n", len);
+ }
+
+} /* sndbuf_func() */
+
+static void
+rcvbuf_func(char *argv0, int sk, int len, int set)
+{
+ int error;
+ socklen_t optlen;
+
+ if (set) {
+ error = setsockopt(sk, SOL_SOCKET, SO_RCVBUF,
+ (char *)&len, sizeof(len));
+ } else {
+ optlen = sizeof(len);
+ error = getsockopt(sk, SOL_SOCKET, SO_RCVBUF,
+ (char *)&len, &optlen);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: Error setting/getting rcvbuf: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ if (!set) {
+ printf("rcvbuf is %d.\n", len);
+ }
+
+} /* rcvbuf_func() */
+
+
+static struct sockaddr *
+get_bindx_addr(char *in, int *count)
+{
+
+ struct sockaddr *tmp_addrs = NULL;
+ char *p = in;
+
+ /* Set the buffer for address parsing. */
+ while ('\n' != *p) {
+ p++;
+ }
+ *p = '\0';
+
+ *count = 0;
+
+ tmp_addrs = append_addr(in, tmp_addrs, count);
+ if (NULL == tmp_addrs) {
+ /* We have no memory, so keep fprintf()
+ * from trying to allocate more.
+ */
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", in);
+ exit(2);
+ }
+ return tmp_addrs;
+
+} /* get_bindx_addr() */
+
+static int
+bindx_func(char *argv0, int sk, struct sockaddr *addrs, int count, int flag, int portnum)
+{
+
+ int error;
+ int i;
+ struct sockaddr *sa_addr;
+ void *aptr;
+
+
+ if (0 == portnum) {
+ fprintf(stderr, "%s: A non-0 local port number is ", argv0);
+ fprintf(stderr, "required for bindx to work!\n");
+ return -1 ;
+ }
+
+ /* Set the port in every address. */
+ aptr = addrs;
+ for (i = 0; i < count; i++) {
+ sa_addr = (struct sockaddr *)aptr;
+
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa_addr)->sin_port =
+ htons(portnum);
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa_addr)->sin6_port =
+ htons(portnum);
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ fprintf(stderr, "Invalid address family\n");
+ return -1;
+ }
+ }
+
+ error = sctp_bindx(sk, addrs, count, flag);
+
+ if (error != 0) {
+ if (flag == SCTP_BINDX_ADD_ADDR) {
+ fprintf(stderr, "%s: error adding addrs: %s.\n",
+ argv0, strerror(errno));
+ return -1;
+ } else {
+ fprintf(stderr, "%s: error removing addrs: %s.\n",
+ argv0, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+
+} /* bindx_func() */
+
+static int
+connectx_func(char *argv0, int sk, struct sockaddr *addrs, int count)
+{
+
+ int error;
+ int i;
+ struct sockaddr *sa_addr;
+ void *aptr;
+
+
+ if (0 == remote_port) {
+ fprintf(stderr, "%s: A non-0 remote port number is ", argv0);
+ fprintf(stderr, "required for connectx to work!\n");
+ return -1 ;
+ }
+
+ /* Set the port in every address. */
+ aptr = addrs;
+ for (i = 0; i < count; i++) {
+ sa_addr = (struct sockaddr *)aptr;
+
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa_addr)->sin_port =
+ htons(remote_port);
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa_addr)->sin6_port =
+ htons(remote_port);
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ fprintf(stderr, "Invalid address family\n");
+ return -1;
+ }
+ }
+
+ error = sctp_connectx(sk, addrs, count, NULL);
+
+ if (error != 0) {
+ if (errno == ECONNREFUSED)
+ return -2;
+ fprintf(stderr, "%s: error connecting to addrs: %s.\n",
+ argv0, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+
+} /* connectx_func() */
+
+static void
+primary_func(char *argv0, int sk, char *cp, int set)
+{
+ struct sctp_prim prim;
+ struct sockaddr_in *in_addr;
+ struct sockaddr_in6 *in6_addr;
+ struct sockaddr *saddr;
+ socklen_t prim_len;
+ int ret;
+ char *p = cp;
+ char addr_buf[INET6_ADDRSTRLEN];
+ const char *ap = NULL;
+
+ prim_len = sizeof(struct sctp_prim);
+ if (!set) {
+ prim.ssp_assoc_id = associd;
+ ret = getsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR,
+ &prim, &prim_len);
+ if (ret < 0)
+ goto err;
+
+ saddr = (struct sockaddr *)&prim.ssp_addr;
+ if (AF_INET == saddr->sa_family) {
+ in_addr = (struct sockaddr_in *)&prim.ssp_addr;
+ ap = inet_ntop(AF_INET, &in_addr->sin_addr, addr_buf,
+ INET6_ADDRSTRLEN);
+ } else if (AF_INET6 == saddr->sa_family) {
+ in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr;
+ ap = inet_ntop(AF_INET6, &in6_addr->sin6_addr, addr_buf,
+ INET6_ADDRSTRLEN);
+ }
+ if (!ap)
+ goto err;
+ printf("%s\n", ap);
+ return;
+ }
+
+ /* Set the buffer for address parsing. */
+ while ('\n' != *p)
+ p++;
+ *p = '\0';
+
+ prim.ssp_assoc_id = associd;
+ if (strchr(cp, '.')) {
+ in_addr = (struct sockaddr_in *)&prim.ssp_addr;
+ in_addr->sin_port = htons(remote_port);
+ in_addr->sin_family = AF_INET;
+ ret = inet_pton (AF_INET, cp, &in_addr->sin_addr);
+ if (ret <= 0)
+ goto err;
+ } else if (strchr(cp, ':')) {
+ in6_addr = (struct sockaddr_in6 *)&prim.ssp_addr;
+ in6_addr->sin6_port = htons(remote_port);
+ in6_addr->sin6_family = AF_INET6;
+ ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+ if (ret <= 0)
+ goto err;
+ } else
+ goto err;
+
+ ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PRIMARY_ADDR,
+ &prim, sizeof(struct sctp_prim));
+ if (ret < 0)
+ goto err;
+
+ return;
+err:
+ if (!errno)
+ errno = EINVAL;
+ fprintf(stderr, "%s: error %s primary: %s.\n", argv0,
+ (set)?"setting":"getting", strerror(errno));
+}
+
+static void
+peer_primary_func(char *argv0, int sk, char *cp, int set)
+{
+ struct sctp_setpeerprim setpeerprim;
+ struct sockaddr_in *in_addr;
+ struct sockaddr_in6 *in6_addr;
+ int ret;
+ char *p = cp;
+
+ if (!set) {
+ goto err;
+ }
+
+ /* Set the buffer for address parsing. */
+ while ('\n' != *p)
+ p++;
+ *p = '\0';
+
+ setpeerprim.sspp_assoc_id = associd;
+ if (strchr(cp, '.')) {
+ in_addr = (struct sockaddr_in *)&setpeerprim.sspp_addr;
+ in_addr->sin_port = htons(local_port);
+ in_addr->sin_family = AF_INET;
+ ret = inet_pton (AF_INET, cp, &in_addr->sin_addr);
+ if (ret <= 0)
+ goto err;
+ } else if (strchr(cp, ':')) {
+ in6_addr = (struct sockaddr_in6 *)&setpeerprim.sspp_addr;
+ in6_addr->sin6_port = htons(local_port);
+ in6_addr->sin6_family = AF_INET6;
+ ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+ if (ret <= 0)
+ goto err;
+ } else
+ goto err;
+
+ ret = setsockopt(sk, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR,
+ &setpeerprim, sizeof(struct sctp_setpeerprim));
+ if (ret < 0)
+ goto err;
+
+ return;
+err:
+ if (!errno)
+ errno = EINVAL;
+ fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0,
+ (set)?"setting":"getting", strerror(errno));
+}
+
+static void
+spp_hb_demand_func(char *argv0, int sk, char *cp, int set)
+{
+ struct sctp_paddrparams params;
+ struct sockaddr_in *in_addr;
+ struct sockaddr_in6 *in6_addr;
+ int ret;
+ char *p = cp;
+
+ memset(¶ms, 0, sizeof(struct sctp_paddrparams));
+ params.spp_assoc_id = associd;
+ params.spp_flags = SPP_HB_DEMAND;
+
+ if (set) {
+ /* Set the buffer for address parsing. */
+ while ('\n' != *p)
+ p++;
+ *p = '\0';
+
+ if (strchr(cp, '.')) {
+ in_addr = (struct sockaddr_in *)¶ms.spp_address;
+ in_addr->sin_port = htons(remote_port);
+ in_addr->sin_family = AF_INET;
+ ret = inet_pton(AF_INET, cp, &in_addr->sin_addr);
+ if (ret <= 0)
+ goto err;
+ } else if (strchr(cp, ':')) {
+ in6_addr = (struct sockaddr_in6 *)¶ms.spp_address;
+ in6_addr->sin6_port = htons(remote_port);
+ in6_addr->sin6_family = AF_INET6;
+ ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
+ if (ret <= 0)
+ goto err;
+ } else
+ goto err;
+ }
+
+ ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
+ ¶ms, sizeof(struct sctp_paddrparams));
+ if (ret < 0)
+ goto err;
+
+ return;
+err:
+ if (!errno)
+ errno = EINVAL;
+ fprintf(stderr, "%s: error %s peer_addr_params: %s.\n", argv0,
+ (set)?"setting":"getting", strerror(errno));
+}
+
+static int
+nodelay_func(char *argv0, int sk, int val, int set)
+{
+ socklen_t optlen;
+ int error;
+
+ if (set) {
+ error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY,
+ (char *)&val, sizeof(val));
+ } else {
+ optlen = sizeof(val);
+ error = getsockopt(sk, SOL_SCTP, SCTP_NODELAY,
+ (char *)&val, &optlen);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: Error setting/getting nodelay: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ if (!set) {
+ printf("nodelay is %d.\n", val);
+ }
+
+ return error;
+}
+
+static int
+maxseg_func(char *argv0, int sk, int val, int set)
+{
+ socklen_t optlen;
+ int error;
+
+ if (set) {
+ error = setsockopt(sk, SOL_SCTP, SCTP_MAXSEG,
+ (char *)&val, sizeof(val));
+ } else {
+ optlen = sizeof(val);
+ error = getsockopt(sk, SOL_SCTP, SCTP_MAXSEG,
+ (char *)&val, &optlen);
+ }
+ if (error != 0) {
+ fprintf(stderr, "%s: Error setting/getting maxseg: %s.\n",
+ argv0, strerror(errno));
+ exit(1);
+ }
+
+ if (!set) {
+ printf("maxseg is %d.\n", val);
+ }
+
+ return error;
+}
+
+static int
+shutdown_func(char *argv0, int *skp, int shutdown_type)
+{
+ struct msghdr outmessage;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ int error=0, bytes_sent;
+ struct sctp_sndrcvinfo *sinfo;
+ struct hostent *hst;
+ char *sd_type;
+ int sk = *skp;
+
+ if (shutdown_type == SHUTDOWN_ABORT)
+ sd_type = "ABORT";
+ else
+ sd_type = "SHUTDOWN";
+
+ /* Verify that the association is present. */
+ error = test_sk_for_assoc(sk, associd);
+ if (error != 0) {
+ printf("The association isn't present yet! Cannot %s!\n", sd_type);
+ return -1;
+ }
+
+ if (socket_type == SOCK_SEQPACKET) {
+ /* Set up the destination. */
+ if (remote_host) {
+ hst = gethostbyname(remote_host);
+ if (hst == NULL) {
+ hst = gethostbyname2(remote_host, AF_INET6);
+ }
+
+ if (hst == NULL || hst->h_length < 1) {
+ fprintf(stderr, "%s: bad hostname: %s\n",
+ argv0, remote_host);
+ exit(1);
+ }
+
+ ra_family = hst->h_addrtype;
+ switch (ra_family) {
+ case AF_INET:
+ ra_len = sizeof(remote_addr.v4);
+ ra_raw = &remote_addr.v4.sin_addr;
+ remote_addr.v4.sin_port = htons(remote_port);
+ remote_addr.v4.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ ra_len = sizeof(remote_addr.v6);
+ ra_raw = &remote_addr.v6.sin6_addr;
+ remote_addr.v6.sin6_port = htons(remote_port);
+ remote_addr.v6.sin6_family = AF_INET6;
+ break;
+ default:
+ fprintf(stderr, "Invalid address type.\n");
+ exit(1);
+ break;
+ }
+ memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
+ }
+
+ /* Initialize the message struct we use to pass messages to
+ * the remote socket.
+ */
+ outmessage.msg_name = &remote_addr;
+ outmessage.msg_namelen = ra_len;
+
+ outmessage.msg_iov = NULL;
+ outmessage.msg_iovlen = 0;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ if (shutdown_type == SHUTDOWN_ABORT)
+ sinfo->sinfo_flags |= SCTP_ABORT;
+ else
+ sinfo->sinfo_flags |= SCTP_EOF;
+
+ sinfo->sinfo_assoc_id = associd;
+
+ bytes_sent = sendmsg(sk, &outmessage, 0);
+ if (bytes_sent != 0) {
+ printf("Failure: %s.\n", strerror(errno));
+ return -1;
+ }
+
+ /* Receive the COMM_LOST or SHUTDOWN_COMP event. */
+ test_recv_assoc_change(sk);
+ } else {
+ if (shutdown_type == SHUTDOWN_ABORT) {
+ struct linger {
+ int l_onoff;
+ int l_linger;
+ } data = {1, 0};
+ error = setsockopt(sk, SOL_SOCKET, SO_LINGER,
+ (char *)&data, sizeof(data));
+ if (error != 0) {
+ printf("setsockopt failed %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ error = close(sk);
+ if (error != 0) {
+ printf("close failed %s\n", strerror(errno));
+ exit(1);
+ }
+ *skp = sk = build_endpoint(argv0, local_port);
+ }
+
+ /* Verify that the association is no longer present. */
+ error = test_sk_for_assoc(sk, associd);
+ if (error != 0) {
+ printf("Successfully %s the original association\n", sd_type);
+ associd = 0;
+ new_connection = 1;
+ } else {
+ printf("%s failed\n", sd_type);
+ exit(1);
+ }
+
+ return 0;
+}
+
+static int
+get_assocstats_func(int sk, sctp_assoc_t assoc_id)
+{
+ int error = 0;
+ struct sctp_assoc_stats stats;
+ socklen_t len;
+
+ if (assoc_id == 0) {
+ printf("No association present yet\n");
+ return -1;
+ }
+
+ memset(&stats, 0, sizeof(struct sctp_assoc_stats));
+ stats.sas_assoc_id = assoc_id;
+ len = sizeof(struct sctp_assoc_stats);
+ error = getsockopt(sk, SOL_SCTP, SCTP_GET_ASSOC_STATS,
+ (char *)&stats, &len);
+ if (error != 0) {
+ printf("get_assoc_stats() failed %s\n", strerror(errno));
+ return error;
+ }
+
+ printf("Retransmitted Chunks: %" PRIu64 "\n", (uint64_t) stats.sas_rtxchunks);
+ printf("Gap Acknowledgements Received: %" PRIu64 "\n", (uint64_t) stats.sas_gapcnt);
+ printf("TSN received > next expected: %" PRIu64 "\n", (uint64_t) stats.sas_outofseqtsns);
+ printf("SACKs sent: %" PRIu64 "\n", (uint64_t) stats.sas_osacks);
+ printf("SACKs received: %" PRIu64 "\n", (uint64_t) stats.sas_isacks);
+ printf("Control chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_octrlchunks);
+ printf("Control chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_ictrlchunks);
+ printf("Ordered data chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_oodchunks);
+ printf("Ordered data chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_iodchunks);
+ printf("Unordered data chunks sent: %" PRIu64 "\n", (uint64_t) stats.sas_ouodchunks);
+ printf("Unordered data chunks received: %" PRIu64 "\n", (uint64_t) stats.sas_iuodchunks);
+ printf("Dups received (ordered+unordered): %" PRIu64 "\n", (uint64_t) stats.sas_idupchunks);
+ printf("Packets sent: %" PRIu64 "\n", (uint64_t) stats.sas_opackets);
+ printf("Packets received: %" PRIu64 "\n", (uint64_t) stats.sas_ipackets);
+ printf("Maximum Observed RTO this period: %" PRIu64 " - Transport: ", (uint64_t) stats.sas_maxrto);
+ print_sockaddr((struct sockaddr *)&stats.sas_obs_rto_ipaddr);
+ printf("\n");
+
+ return 0;
+}
+
+static int
+test_sk_for_assoc(int sk, sctp_assoc_t assoc_id)
+{
+ int error = 0;
+ struct sctp_status status;
+ socklen_t status_len;
+
+ memset(&status, 0, sizeof(status));
+ if (assoc_id)
+ status.sstat_assoc_id = assoc_id;
+ status_len = sizeof(struct sctp_status);
+ error = getsockopt(sk, SOL_SCTP, SCTP_STATUS,
+ (char *)&status, &status_len);
+ return error;
+}
+
+/* Receive a notification and return the corresponding associd if the event is
+ * SCTP_COMM_UP. Return 0 for any other event.
+ */
+static sctp_assoc_t
+test_recv_assoc_change(int sk)
+{
+ struct msghdr inmessage;
+ struct iovec iov;
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ int error;
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ printf("%s: Can't allocate memory.\n", __FUNCTION__);
+ exit(1);
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ error = recvmsg(sk, &inmessage, MSG_WAITALL);
+ if (error < 0) {
+ printf("%s: recvmsg: %s\n", __FUNCTION__, strerror(errno));
+ exit(1);
+ }
+
+ return test_verify_assoc_change(&inmessage);
+}
+
+/* Verify a notification and return the corresponding associd if the event is
+ * SCTP_COMM_UP. Return 0 for any other event.
+ */
+static sctp_assoc_t
+test_verify_assoc_change(struct msghdr *msg)
+{
+ union sctp_notification *sn;
+
+ if (!(msg->msg_flags & MSG_NOTIFICATION)) {
+ fprintf(stderr, "%s: Received data when notification is expected\n",
+ __FUNCTION__);
+ exit(1);
+ }
+
+ sn = (union sctp_notification *)msg->msg_iov->iov_base;
+ if (SCTP_ASSOC_CHANGE != sn->sn_header.sn_type) {
+ fprintf(stderr, "%s: Received unexpected notification: %d",
+ __FUNCTION__, sn->sn_header.sn_type);
+ exit(1);
+ }
+
+ switch(sn->sn_assoc_change.sac_state)
+ {
+ case SCTP_COMM_UP:
+ printf("Received SCTP_COMM_UP\n");
+ break;
+ case SCTP_COMM_LOST:
+ printf("Received SCTP_COMM_LOST\n");
+ break;
+ case SCTP_RESTART:
+ printf("Received SCTP_RESTART\n");
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ printf("Received SCTP_SHUTDOWN_COMP\n");
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ printf("Received SCTP_CANT_STR_ASSOC\n");
+ break;
+ }
+
+ if (SCTP_COMM_UP == sn->sn_assoc_change.sac_state)
+ return sn->sn_assoc_change.sac_assoc_id;
+ else
+ return 0;
+}
+
+void print_addr_buf(void * laddrs, int n_laddrs)
+{
+ void *addr_buf = laddrs;
+ int i;
+
+ for (i = 0; i < n_laddrs; i++) {
+ addr_buf += print_sockaddr((struct sockaddr *)addr_buf);
+ printf("\n");
+ }
+}
+
+int print_sockaddr(struct sockaddr *sa_addr)
+{
+ struct sockaddr_in *in_addr;
+ struct sockaddr_in6 *in6_addr;
+
+ if (AF_INET == sa_addr->sa_family) {
+ in_addr = (struct sockaddr_in *)sa_addr;
+ printf("%d.%d.%d.%d:%d",
+ NIPQUAD(in_addr->sin_addr),
+ ntohs(in_addr->sin_port));
+ return sizeof(struct sockaddr_in);
+ } else {
+ in6_addr = (struct sockaddr_in6 *)sa_addr;
+ printf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%d",
+ NIP6(in6_addr->sin6_addr),
+ ntohs(in6_addr->sin6_port));
+ return sizeof(struct sockaddr_in6);
+ }
+}
diff --git a/src/apps/sctp_darn.h b/src/apps/sctp_darn.h
new file mode 100644
index 0000000..e2c1ef1
--- /dev/null
+++ b/src/apps/sctp_darn.h
@@ -0,0 +1,29 @@
+#ifndef __sctp_darn_h__
+#define __sctp_darn_h__
+
+#define REALLY_BIG 65536
+#define SCTP_TESTPORT_1 1
+#define SCTP_TESTPORT_2 2
+
+void parse_arguments(int argc, char *argv[]);
+void usage(char *argv0);
+int command_listen(char *arg0, int sk);
+int command_send(char *arg0, int *skp);
+int command_poll(char *arg0);
+int test_print_message(int sk, struct msghdr *, size_t msg_len);
+
+typedef enum {
+ COMMAND_NONE = 0,
+ COMMAND_LISTEN,
+ COMMAND_SEND,
+ COMMAND_POLL,
+} command_t;
+
+typedef union {
+ struct sockaddr_storage ss;
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ struct sockaddr sa;
+} sockaddr_storage_t;
+
+#endif /* __sctp_darn_h__ */
diff --git a/src/apps/sctp_status.c b/src/apps/sctp_status.c
new file mode 100644
index 0000000..8563cbe6
--- /dev/null
+++ b/src/apps/sctp_status.c
@@ -0,0 +1,945 @@
+/* SCTP kernel reference Implementation
+ * (C) Copyright Fujitsu Ltd. 2008, 2009
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Wei Yongjun <yjwei@cn.fujitsu.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/sctp.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+
+#define DEFAULT_SEC 0
+#define DEFAULT_USEC 5000
+
+#define REALLY_BIG 65536
+
+#define SERVER 0
+#define CLIENT 1
+#define NOT_DEFINED 666
+
+#define DEBUG_NONE 0
+#define DEBUG_MIN 1
+#define DEBUG_MAX 2
+
+#define ORDER_PATTERN_UNORDERED 0
+#define ORDER_PATTERN_ORDERED 1
+#define ORDER_PATTERN_ALTERNATE 2
+#define ORDER_PATTERN_RANDOM 3
+
+#define STREAM_PATTERN_SEQUENTIAL 0
+#define STREAM_PATTERN_RANDOM 1
+
+#define MAX_BIND_RETRYS 10
+#define BIG_REPEAT 1000000
+#define REPEAT 10
+
+#define DEFAULT_MAX_WINDOW 32768
+#define DEFAULT_MIN_WINDOW 1500
+
+#define MSG_CNT 10
+
+#define DEBUG_PRINT(level, print_this...) \
+{ \
+ if (debug_level >= level) { \
+ fprintf(stdout, print_this); \
+ fflush(stdout); \
+ } \
+} /* DEBUG_PRINT */
+
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+struct sockaddr_storage s_rem, s_loc;
+int r_len, l_len;
+int size_arg = 0;
+int debug_level = DEBUG_NONE;
+int order_pattern = ORDER_PATTERN_UNORDERED;
+int order_state = 0;
+int stream_pattern = STREAM_PATTERN_SEQUENTIAL;
+int stream_state = 0;
+int repeat = REPEAT;
+int repeat_count = 0;
+int max_msgsize = DEFAULT_MAX_WINDOW;
+int msg_cnt = MSG_CNT;
+int drain = 0;
+int max_stream = 0;
+int gsk = -1;
+int period = 1;
+char *statusfile = NULL;
+
+void printstatus(int sk);
+void sighandler(int signo);
+void settimerhandle(void);
+void usage(char *argv0);
+void start_test(int role);
+
+unsigned char msg[] = "012345678901234567890123456789012345678901234567890";
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+ struct sctp_initmsg init;
+ struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+int main(int argc, char *argv[]) {
+ int c, role = NOT_DEFINED;
+ char *interface = NULL;
+ struct sockaddr_in *t_addr;
+ struct sockaddr_in6 *t_addr6;
+
+ /* Parse the arguments. */
+ while ((c = getopt(argc, argv, ":H:L:P:h:p:c:d:lm:sx:X:o:M:Di:I:f:")) >= 0 ) {
+ switch (c) {
+ case 'H':
+ local_host = optarg;
+ break;
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ case 'l':
+ if (role != NOT_DEFINED) {
+ printf("%s: only -s or -l\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ role = SERVER;
+ break;
+ case 's':
+ if (role != NOT_DEFINED) {
+ printf("%s: only -s or -l\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ role = CLIENT;
+ break;
+ case 'D':
+ drain = 1;
+ break;
+ case 'd':
+ debug_level = atoi(optarg);
+ if (debug_level < DEBUG_NONE
+ || debug_level > DEBUG_MAX) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'I':
+ period = atoi(optarg);
+ if (period < 0) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'x':
+ repeat = atoi(optarg);
+ if (!repeat) {
+ repeat = BIG_REPEAT;
+ }
+ break;
+ case 'X':
+ msg_cnt = atoi(optarg);
+ if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'c':
+ size_arg = atoi(optarg);
+ if (size_arg < 0) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ break;
+ case 'o':
+ order_pattern = atoi(optarg);
+ if (order_pattern < ORDER_PATTERN_UNORDERED
+ || order_pattern > ORDER_PATTERN_RANDOM ) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'M':
+ max_stream = atoi(optarg);
+ if (max_stream < 0
+ || max_stream >= (1<<16)) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'm':
+ max_msgsize = atoi(optarg);
+ break;
+ case 'i':
+ interface = optarg;
+ break;
+ case 'f':
+ statusfile = optarg;
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ exit(0);
+ }
+ } /* while() */
+
+ if (NOT_DEFINED == role) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (SERVER == role && NULL == local_host && remote_host != NULL) {
+ fprintf(stderr, "%s: Server needs local address, "
+ "not remote address\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ if (CLIENT == role && NULL == remote_host) {
+ fprintf(stderr, "%s: Client needs at least remote address "
+ "& port\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "%s: non-option arguments are illegal: ", argv[0]);
+ while (optind < argc)
+ fprintf(stderr, "%s ", argv[optind++]);
+ fprintf (stderr, "\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (remote_host != NULL && remote_port != 0) {
+ struct addrinfo *res;
+ int error;
+ char *host_s, *serv_s;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ error = getaddrinfo(remote_host, 0, NULL, &res);
+ if (error) {
+ printf("%s.\n", gai_strerror(error));
+ usage(argv[0]);
+ exit(1);
+ }
+
+ switch (res->ai_family) {
+ case AF_INET:
+ t_addr = (struct sockaddr_in *)&s_rem;
+
+ memcpy(t_addr, res->ai_addr,
+ res->ai_addrlen);
+ t_addr->sin_family = res->ai_family;
+ t_addr->sin_port = htons(remote_port);
+
+ r_len = res->ai_addrlen;
+#ifdef __FreeBSD__
+ t_addr->sin_len = r_len;
+#endif
+ break;
+ case AF_INET6:
+ t_addr6 = (struct sockaddr_in6 *)&s_rem;
+
+ memcpy(t_addr6, res->ai_addr,
+ res->ai_addrlen);
+ t_addr6->sin6_family = res->ai_family;
+ t_addr6->sin6_port = htons(remote_port);
+ if (interface)
+ t_addr6->sin6_scope_id = if_nametoindex(interface);
+
+ r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr6->sin6_len = r_len;
+#endif
+ break;
+ }
+
+ getnameinfo((struct sockaddr *)&s_rem, r_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+ DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n",
+ host_s, serv_s, res->ai_family);
+
+ freeaddrinfo(res);
+ }
+
+ if (local_host != NULL) {
+ struct addrinfo *res;
+ int error;
+ char *host_s, *serv_s;
+ struct sockaddr_in *t_addr;
+ struct sockaddr_in6 *t_addr6;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ if (strcmp(local_host, "0") == 0)
+ local_host = "0.0.0.0";
+
+ error = getaddrinfo(local_host, 0, NULL, &res);
+ if (error) {
+ printf("%s.\n", gai_strerror(error));
+ usage(argv[0]);
+ exit(1);
+ }
+
+ switch (res->ai_family) {
+ case AF_INET:
+ t_addr = (struct sockaddr_in *)&s_loc;
+
+ memcpy(t_addr, res->ai_addr,
+ res->ai_addrlen);
+ t_addr->sin_family = res->ai_family;
+ t_addr->sin_port = htons(local_port);
+
+ l_len = res->ai_addrlen;
+#ifdef __FreeBSD__
+ t_addr->sin_len = l_len;
+#endif
+ break;
+ case AF_INET6:
+ t_addr6 = (struct sockaddr_in6 *)&s_loc;
+
+ memcpy(t_addr6, res->ai_addr,
+ res->ai_addrlen);
+ t_addr6->sin6_family = res->ai_family;
+ t_addr6->sin6_port = htons(local_port);
+ if (interface)
+ t_addr6->sin6_scope_id = if_nametoindex(interface);
+
+ l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr6->sin6_len = l_len;
+#endif
+ break;
+ }
+
+ error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+ if (error)
+ printf("%s..\n", gai_strerror(error));
+
+ DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n",
+ host_s, serv_s, res->ai_family);
+
+ freeaddrinfo(res);
+ }
+
+ /* Let the testing begin. */
+ start_test(role);
+
+ return 0;
+}
+
+int bind_r(int sk, struct sockaddr_storage *saddr) {
+ int error = 0, i = 0;
+ char *host_s, *serv_s;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ do {
+ if (i > 0) sleep(1); /* sleep a while before new try... */
+
+ error = getnameinfo((struct sockaddr *)saddr, l_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV,
+ NI_NUMERICHOST);
+
+ if (error)
+ printf("%s\n", gai_strerror(error));
+
+ DEBUG_PRINT(DEBUG_MIN,
+ "\tbind(sk=%d, [a:%s,p:%s]) -- attempt %d/%d\n",
+ sk, host_s, serv_s, i+1, MAX_BIND_RETRYS);
+
+ error = bind(sk, (struct sockaddr *)saddr, l_len);
+
+ if (error != 0) {
+ if( errno != EADDRINUSE ) {
+ fprintf(stderr, "\n\n\t\t***bind: can "
+ "not bind to %s:%s: %s ****\n",
+ host_s, serv_s, strerror(errno));
+ exit(1);
+ }
+ }
+ i++;
+ if (i >= MAX_BIND_RETRYS) {
+ fprintf(stderr, "Maximum bind() attempts. "
+ "Die now...\n\n");
+ exit(1);
+ }
+ } while (error < 0 && i < MAX_BIND_RETRYS);
+
+ return 0;
+} /* bind_r() */
+
+int listen_r(int sk, int listen_count) {
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n",
+ sk, listen_count);
+
+ /* Mark sk as being able to accept new associations */
+ error = listen(sk, 1);
+ if (error != 0) {
+ fprintf(stderr, "\n\n\t\t*** listen: %s ***\n\n\n", strerror(errno));
+ exit(1);
+ }
+
+ return 0;
+} /* listen_r() */
+
+int accept_r(int sk){
+ socklen_t len = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk);
+
+ gsk = accept(sk, NULL, &len);
+ if (gsk < 0) {
+ fprintf(stderr, "\n\n\t\t*** accept: %s ***\n\n\n", strerror(errno));
+ exit(1);
+ }
+
+ return 0;
+} /* accept_r() */
+
+int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen) {
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk);
+
+ /* Mark sk as being able to accept new associations */
+ error = connect(sk, serv_addr, addrlen);
+ if (error != 0) {
+ fprintf(stderr, "\n\n\t\t*** connect: %s ***\n\n\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ gsk = sk;
+
+ return 0;
+} /* connect_r() */
+
+int close_r(int sk) {
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk);
+
+ error = close(sk);
+ if (error != 0) {
+ fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n",
+ strerror(errno));
+ exit(1);
+ }
+ fflush(stdout);
+ return 0;
+} /* close_r() */
+
+int receive_r(int sk)
+{
+ int error = 0;
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ struct msghdr inmessage;
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+ exit(1);
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /* Get the messages sent */
+ while (1) {
+ DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk);
+
+ error = recvmsg(sk, &inmessage, MSG_WAITALL);
+ if (error < 0 && errno != EAGAIN) {
+ fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n",
+ strerror(errno));
+ fflush(stdout);
+ close(sk);
+ free(iov.iov_base);
+ exit(1);
+ } else if (error == 0) {
+ printf("\n\t\trecvmsg() returned 0 !!!!\n");
+ fflush(stdout);
+ }
+
+ if(MSG_NOTIFICATION & inmessage.msg_flags)
+ continue; /* got a notification... */
+
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ iov.iov_len = REALLY_BIG;
+ break;
+ }
+
+ free(iov.iov_base);
+ return 0;
+} /* receive_r () */
+
+void server(int sk) {
+ int i;
+
+ if (max_msgsize > DEFAULT_MAX_WINDOW) {
+ if (setsockopt(sk, IPPROTO_SCTP, SO_RCVBUF, &max_msgsize,
+ sizeof(max_msgsize)) < 0) {
+ perror("setsockopt(SO_RCVBUF)");
+ exit(1);
+ }
+ }
+
+ for (i = 0; i < msg_cnt; i++) {
+ receive_r(sk);
+ DEBUG_PRINT(DEBUG_MIN, "count %d\n", i+1);
+ }
+} /* server() */
+
+void * build_msg(int len) {
+ int i = len - 1;
+ int n;
+ char *msg_buf, *p;
+
+ msg_buf = malloc(len);
+ if (NULL == msg_buf) {
+ fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+ exit(1);
+ }
+ p = msg_buf;
+
+ do {
+ n = ((i > 50)?50:i);
+ memcpy(p, msg, ((i > 50)?50:i));
+ p += n;
+ i -= n;
+ } while (i > 0);
+
+ msg_buf[len-1] = '\0';
+
+ return(msg_buf);
+
+} /* build_msg() */
+
+int send_r(int sk, int stream, int order, int send_size, int assoc_i) {
+ int error = 0;
+ struct msghdr outmsg;
+ struct iovec iov;
+ char *message = NULL;
+ int msglen = 0;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+
+ if (send_size > 0) {
+ message = build_msg(send_size);
+ msglen = strlen(message) + 1;
+ iov.iov_base = message;
+ iov.iov_len = msglen;
+ } else {
+ exit(1);
+ }
+
+ outmsg.msg_name = &s_rem;
+ outmsg.msg_namelen = sizeof(struct sockaddr_storage);
+ outmsg.msg_iov = &iov;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = outcmsg;
+ outmsg.msg_controllen = sizeof(outcmsg);
+ outmsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmsg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ outmsg.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_ppid = rand();
+ sinfo->sinfo_stream = stream;
+ sinfo->sinfo_flags = 0;
+ if (!order)
+ sinfo->sinfo_flags = SCTP_UNORDERED;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",
+ sk, assoc_i, send_size);
+ DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV");
+ if (DEBUG_MAX == debug_level) {
+ printf("(stream=%u ", sinfo->sinfo_stream);
+ printf("flags=0x%x ", sinfo->sinfo_flags);
+ printf("ppid=%u)\n", sinfo->sinfo_ppid);
+ }
+
+ /* Send to our neighbor. */
+ error = sendmsg(sk, &outmsg, MSG_WAITALL);
+ if (error != msglen) {
+ fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",
+ strerror(errno));
+ fflush(stdout);
+ exit(1);
+ }
+
+ if (send_size > 0) free(message);
+ return 0;
+} /* send_r() */
+
+int next_order(int state, int pattern)
+{
+ switch (pattern){
+ case ORDER_PATTERN_UNORDERED:
+ state = 0;
+ break;
+ case ORDER_PATTERN_ORDERED:
+ state = 1;
+ break;
+ case ORDER_PATTERN_ALTERNATE:
+ state = state ? 0 : 1;
+ break;
+ case ORDER_PATTERN_RANDOM:
+ state = rand() % 2;
+ break;
+ }
+
+ return state;
+}
+
+int next_stream(int state, int pattern)
+{
+ switch (pattern){
+ case STREAM_PATTERN_RANDOM:
+ state = rand() % max_stream;
+ break;
+ case STREAM_PATTERN_SEQUENTIAL:
+ state = state + 1;
+ if (state >= max_stream)
+ state = 0;
+ break;
+ }
+
+ return state;
+}
+
+int next_msg_size(int msg_cnt)
+{
+ int msg_size;
+
+ if (size_arg) {
+ msg_size = size_arg;
+ } else {
+ msg_size = (rand() % max_msgsize) + 1;
+ }
+
+ return msg_size;
+
+} /* next_msg_size() */
+
+void client(int sk) {
+ int msg_size;
+ int i;
+
+ for (i = 0; i < msg_cnt; i++) {
+ msg_size = next_msg_size(i);
+ order_state = next_order(order_state, order_pattern);
+ stream_state = next_stream(stream_state, stream_pattern);
+
+ if (send_r(sk, stream_state, order_state, msg_size, 0) < 0) {
+ close(sk);
+ break;
+ }
+
+ /* The sender is echoing so do discard the echoed data. */
+ if (drain && ((i + 1) % period == 0)) {
+ receive_r(sk);
+ }
+ }
+} /* client() */
+
+void start_test(int role) {
+ int sk, pid, ret;
+ int i = 0;
+
+ DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n");
+
+ repeat_count = repeat;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tsocket(SOCK_STREAM, IPPROTO_SCTP)");
+
+ if ((sk = socket(s_loc.ss_family, SOCK_STREAM, IPPROTO_SCTP)) < 0 ) {
+ fprintf(stderr, "\n\n\t\t*** socket: failed to create"
+ " socket: %s ***\n", strerror(errno));
+ exit(1);
+ }
+ DEBUG_PRINT(DEBUG_MIN, " -> sk=%d\n", sk);
+
+ bind_r(sk, &s_loc);
+
+ if (role == SERVER) {
+ listen_r(sk, 1);
+ accept_r(sk);
+ } else {
+ if (max_stream > 0) {
+ struct sctp_initmsg initmsg;
+
+ memset(&initmsg, 0, sizeof(initmsg));
+ initmsg.sinit_num_ostreams = max_stream;
+ initmsg.sinit_max_instreams = max_stream;
+ initmsg.sinit_max_attempts = 3;
+
+ ret = setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG,
+ &initmsg, sizeof(initmsg));
+ if (ret < 0) {
+ perror("setsockopt(SCTP_INITMSG)");
+ exit(0);
+ }
+ }
+
+ connect_r(sk, (struct sockaddr *)&s_rem, r_len);
+ }
+
+ if ((pid = fork()) == 0) {
+ settimerhandle();
+ printstatus(gsk);
+ while(1);
+ } else {
+ if (!debug_level) {
+ printf(" ");
+ }
+
+ for(i = 0; i < repeat_count; i++) {
+
+ if (role == SERVER) {
+ DEBUG_PRINT(DEBUG_NONE, "Server: Receiving packets.(%d/%d)\n",
+ i+1, repeat_count);
+ server(gsk);
+ } else {
+ DEBUG_PRINT(DEBUG_NONE, "Client: Sending packets.(%d/%d)\n",
+ i+1, repeat_count);
+ client(sk);
+ }
+
+ fflush(stdout);
+ }
+
+ if (role == SERVER) close_r(gsk);
+ close_r(sk);
+ }
+} /* start_test() */
+
+void settimerhandle(void) {
+ struct sigaction act;
+ struct itimerval interval;
+
+ act.sa_handler = sighandler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGPROF, &act, NULL);
+
+ interval.it_value.tv_sec = DEFAULT_SEC;
+ interval.it_value.tv_usec = DEFAULT_USEC;
+ interval.it_interval = interval.it_value;
+
+ setitimer(ITIMER_PROF, &interval, NULL);
+}
+
+void usage(char *argv0) {
+ fprintf(stderr, "\nusage:\n");
+ fprintf(stderr, " server:\n");
+ fprintf(stderr, " %8s -H local-addr -P local-port -l [-d level] [-x]\n"
+ "\t [-L num-ports] [-S num-ports]\n"
+ "\t [-a assoc-pattern]\n"
+ "\t [-i interface]\n"
+ "\t [-f status-file]\n",
+ argv0);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " client:\n");
+ fprintf(stderr, " %8s -H local-addr -P local-port -h remote-addr\n"
+ "\t -p remote-port -s [-c case ] [-d level]\n"
+ "\t [-x repeat] [-o order-pattern] ream-pattern]\n"
+ "\t [-M max-stream]\n"
+ "\t [-m max-msgsize]\n"
+ "\t [-L num-ports] [-S num-ports]\n"
+ "\t [-i interface]\n"
+ "\t [-f status-file]\n",
+ argv0);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "\t-c value = Packets of specifed size.\n");
+ fprintf(stderr, "\t-m msgsize(1500-65515, default value 32768)\n");
+ fprintf(stderr, "\t-x number of repeats\n");
+ fprintf(stderr, "\t-X number of messages\n");
+ fprintf(stderr, "\t-o order-pattern\n");
+ fprintf(stderr, "\t 0 = all unordered(default) \n");
+ fprintf(stderr, "\t 1 = all ordered \n");
+ fprintf(stderr, "\t 2 = alternating \n");
+ fprintf(stderr, "\t 3 = random\n");
+ fprintf(stderr, "\t-M max-stream (default value 0)\n");
+ fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n");
+ fprintf(stderr, "\t-I receive after <n> times of send, default value 1.\n");
+ fprintf(stderr, "\n");
+ fflush(stderr);
+
+} /* usage() */
+
+void sighandler(int signo) {
+ DEBUG_PRINT(DEBUG_MAX, "timeout sig\n");
+ printstatus(gsk);
+}
+
+char* get_sstat_state(int state) {
+ switch(state) {
+ case SCTP_EMPTY:
+ return "EMPTY";
+ case SCTP_CLOSED:
+ return "CLOSED";
+ case SCTP_COOKIE_WAIT:
+ return "COOKIE_WAIT";
+ case SCTP_COOKIE_ECHOED:
+ return "COOKIE_ECHOED";
+ case SCTP_ESTABLISHED:
+ return "ESTABLISHED";
+ case SCTP_SHUTDOWN_PENDING:
+ return "SHUTDOWN_PENDING";
+ case SCTP_SHUTDOWN_SENT:
+ return "SHUTDOWN_SENT";
+ case SCTP_SHUTDOWN_RECEIVED:
+ return "SHUTDOWN_RECEIVED";
+ case SCTP_SHUTDOWN_ACK_SENT:
+ return "SHUTDOWN_ACK_SENT";
+ default:
+ return "UNKNOW";
+ }
+}
+
+void printstatus(int sk) {
+ static int cwnd = 0;
+ static int count = 0;
+ struct sctp_status status;
+ socklen_t optlen;
+ FILE * fp;
+ const char *state_to_str[] = {
+ [SCTP_INACTIVE] = "INACTIVE",
+ [SCTP_PF] = "PF",
+ [SCTP_ACTIVE] = "ACTIVE",
+ [SCTP_UNCONFIRMED] = "UNCONFIRMED",
+ };
+
+ optlen = sizeof(struct sctp_status);
+ if(getsockopt(sk, IPPROTO_SCTP, SCTP_STATUS, &status, &optlen) < 0) {
+ fprintf(stderr, "Error getting status: %s.\n", strerror(errno));
+ exit(1);
+ }
+
+ if (statusfile != NULL) {
+ if (count == 0)
+ unlink(statusfile);
+
+ if((fp = fopen(statusfile, "a+")) == NULL) {
+ perror("fopen");
+ exit(1);
+ }
+ } else
+ fp = stdout;
+
+ if (count == 0)
+ fprintf(fp, "NO. ASSOC-ID STATE RWND UNACKDATA PENDDATA INSTRMS OUTSTRMS "
+ "FRAG-POINT SPINFO-STATE SPINFO-CWDN SPINFO-SRTT SPINFO-RTO SPINFO-MTU\n");
+
+ if (cwnd != status.sstat_primary.spinfo_cwnd) {
+ count++;
+
+ fprintf(fp, "%-3d %-8d %-17s %-8d %-9d %-8d %-7d %-8d %-10d %-12s %-11d %-11d %-10d %d\n", count,
+ status.sstat_assoc_id, get_sstat_state(status.sstat_state),
+ status.sstat_rwnd, status.sstat_unackdata, status.sstat_penddata,
+ status.sstat_instrms, status.sstat_outstrms, status.sstat_fragmentation_point,
+ state_to_str[status.sstat_primary.spinfo_state],
+ status.sstat_primary.spinfo_cwnd, status.sstat_primary.spinfo_srtt,
+ status.sstat_primary.spinfo_rto, status.sstat_primary.spinfo_mtu);
+ }
+
+ cwnd = status.sstat_primary.spinfo_cwnd;
+
+ fflush(fp);
+
+ if (fp != stdout)
+ fclose(fp);
+
+ if (status.sstat_primary.spinfo_state != SCTP_ACTIVE) {
+ close_r(sk);
+ exit(1);
+ }
+}
diff --git a/src/apps/sctp_test.c b/src/apps/sctp_test.c
new file mode 100644
index 0000000..cd7654b
--- /dev/null
+++ b/src/apps/sctp_test.c
@@ -0,0 +1,1852 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999 Cisco
+ * Copyright (c) 1999, 2000, 2001 Motorola
+ * Copyright (c) 2001-2002 Nokia
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * This is a userspace test application for the SCTP kernel
+ * implementation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Hui Huang <hui.huang@nokia.com>
+ * Sridhar Samudrala <samudrala@us.ibm.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Ryan Layer <rmlayer@us.ibm.com>
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <net/if.h>
+
+#include <sys/resource.h>
+
+
+#define REALLY_BIG 65536
+
+#define SERVER 0
+#define CLIENT 1
+#define MIXED 2
+#define NOT_DEFINED 666
+
+#define REPEAT 10
+#define BIG_REPEAT 1000000
+#define MAX_BIND_RETRYS 10
+#define BODYSIZE 10
+#define MSG_CNT 10 /* If this is changed the msg_sizes array
+ needs to be modified accordingly. */
+
+#define DEFAULT_MAX_WINDOW 32768
+#define DEFAULT_MIN_WINDOW 1500
+
+#define DEBUG_NONE 0
+#define DEBUG_MIN 1
+#define DEBUG_MAX 2
+
+#define STREAM_PATTERN_SEQUENTIAL 0
+#define STREAM_PATTERN_RANDOM 1
+
+#define ORDER_PATTERN_UNORDERED 0
+#define ORDER_PATTERN_ORDERED 1
+#define ORDER_PATTERN_ALTERNATE 2
+#define ORDER_PATTERN_RANDOM 3
+
+#define ASSOC_PATTERN_SEQUENTIAL 0
+#define ASSOC_PATTERN_RANDOM 1
+
+#define NCASES 6
+#define MAX_POLL_SKS 256
+
+#define DEBUG_PRINT(level, print_this...) \
+{ \
+ if (debug_level >= level) { \
+ fprintf(stdout, print_this); \
+ fflush(stdout); \
+ } \
+} /* DEBUG_PRINT */
+
+/* Convenience structure to determine space needed for cmsg. */
+typedef union {
+ struct sctp_initmsg init;
+ struct sctp_sndrcvinfo sndrcvinfo;
+} _sctp_cmsg_data_t;
+
+#ifdef __FreeBSD__
+typedef union {
+ int raw;
+ struct sctp_initmsg init;
+ struct sctp_sndrcvinfo sndrcv;
+} sctp_cmsg_data_t;
+#endif
+
+#define CMSG_SPACE_INITMSG (CMSG_SPACE(sizeof(struct sctp_initmsg)))
+#define CMSG_SPACE_SNDRCV (CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)))
+
+typedef struct {
+ int rem_port;
+ int order_state;
+ int stream_state;
+ int msg_cnt;
+ int msg_sent;
+ int cycle;
+} _assoc_state;
+
+typedef struct {
+ int sk;
+ int assoc_i;
+ _assoc_state *assoc_state;
+} _poll_sks;
+
+char *local_host = NULL;
+int local_port = 0;
+char *remote_host = NULL;
+int remote_port = 0;
+/* struct sockaddr_in s_rem, s_loc; */
+struct sockaddr_storage s_rem, s_loc;
+int r_len, l_len;
+int test_case = 0;
+int size_arg = 0;
+int xflag = 0;
+int debug_level = DEBUG_MAX;
+int do_exit = 1;
+int stream_pattern = STREAM_PATTERN_SEQUENTIAL;
+int stream_state = 0;
+int order_pattern = ORDER_PATTERN_UNORDERED;
+int order_state = 0;
+int max_stream = 0;
+int seed = 0;
+int max_msgsize = DEFAULT_MAX_WINDOW;
+int timetolive = 0;
+int assoc_pattern = ASSOC_PATTERN_SEQUENTIAL;
+int socket_type = SOCK_SEQPACKET;
+int repeat_count = 0;
+int listeners = 0;
+int tosend = 0;
+_poll_sks poll_sks[MAX_POLL_SKS];
+int repeat = REPEAT;
+int msg_cnt = MSG_CNT;
+int drain = 0;
+int role = NOT_DEFINED;
+struct sockaddr *bindx_add_addrs = NULL;
+int bindx_add_count = 0;
+struct sockaddr *connectx_addrs = NULL;
+int connectx_count = 0;
+int if_index = 0;
+
+unsigned char msg[] = "012345678901234567890123456789012345678901234567890";
+
+static int msg_sizes[NCASES][MSG_CNT] =
+ {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {1452, 2904, 4356, 1452, 2904, 4356, 1452, 2904, 4356, 1452},
+ {1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453},
+ {1, 1453, 32768, 1, 1453, 32768, 1, 1453, 32768, 1},
+ {1, 1000, 2000, 3000, 5000, 10000, 15000, 20000, 25000, 32768},
+ {32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768},
+ };
+
+static const char *sac_state_tbl[] = {
+ "COMMUNICATION_UP",
+ "COMMUNICATION_LOST",
+ "RESTART",
+ "SHUTDOWN_COMPLETE",
+ "CANT_START_ASSOCICATION"
+};
+
+void usage(char *argv0)
+{
+ fprintf(stderr, "\nusage:\n");
+ fprintf(stderr, " server:\n");
+ fprintf(stderr, " %8s -H local-addr -P local-port -l [-d level] [-x]\n"
+ "\t [-L num-ports] [-S num-ports]\n"
+ "\t [-a assoc-pattern]\n"
+ "\t [-i interface]\n",
+ argv0);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " client:\n");
+ fprintf(stderr, " %8s -H local-addr -P local-port -h remote-addr\n"
+ "\t -p remote-port -s [-c case ] [-d level]\n"
+ "\t [-x repeat] [-o order-pattern] [-t stream-pattern]\n"
+ "\t [-M max-stream] [-r rand-seed]\n"
+ "\t [-m max-msgsize]\n"
+ "\t [-L num-ports] [-S num-ports]\n"
+ "\t [-a assoc-pattern]\n"
+ "\t [-i interface]\n",
+ argv0);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "\t-a assoc_pattern in the mixed mode\n");
+ fprintf(stderr, "\t 0 = sequential ascending(default)\n");
+ fprintf(stderr, "\t 1 = random\n");
+ fprintf(stderr, "\t-d debug\n");
+ fprintf(stderr, "\t 0 = none\n");
+ fprintf(stderr, "\t 1 = min(default)\n");
+ fprintf(stderr, "\t 2 = max\n");
+ fprintf(stderr, "\t-c testcase\n");
+ fprintf(stderr, "\t 0 = 1 byte packets.\n");
+ fprintf(stderr, "\t 1 = Sequence of multiples of 1452 byte packets.\n");
+ fprintf(stderr, "\t (1452 is fragmentation point for an i/f with ");
+ fprintf(stderr, "1500 as mtu.)\n");
+ fprintf(stderr, "\t 2 = 1453 byte packets.\n");
+ fprintf(stderr, "\t (min. size at which fragmentation occurs\n");
+ fprintf(stderr, "\t for an i/f with 1500 as mtu.)\n");
+ fprintf(stderr, "\t 3 = Sequence of 1, 1453, 32768 byte packets.\n");
+ fprintf(stderr, "\t 4 = Sequence of following size packets.\n");
+ fprintf(stderr, "\t (1, 1000, 2000, 3000, 5000, 10000,");
+ fprintf(stderr, "15000, 20000, 25000, 32768)\n");
+ fprintf(stderr, "\t 5 = 32768 byte packets.\n");
+ fprintf(stderr, "\t (default max receive window size.)\n");
+ fprintf(stderr, "\t 6 = random size packets.\n");
+ fprintf(stderr, "\t -ve value = Packets of specifed size.\n");
+ fprintf(stderr, "\t-m max msgsize for option -c 6 (1500-65515, default value 32768)\n");
+ fprintf(stderr, "\t-x number of repeats\n");
+ fprintf(stderr, "\t-o order-pattern\n");
+ fprintf(stderr, "\t 0 = all unordered(default) \n");
+ fprintf(stderr, "\t 1 = all ordered \n");
+ fprintf(stderr, "\t 2 = alternating \n");
+ fprintf(stderr, "\t 3 = random\n");
+ fprintf(stderr, "\t-t stream-pattern\n");
+ fprintf(stderr, "\t 0 = sequential ascending(default)\n");
+ fprintf(stderr, "\t 1 = random\n");
+ fprintf(stderr, "\t-M max-stream (default value 0)\n");
+ fprintf(stderr, "\t-r seed (default 0, use time())\n");
+ fprintf(stderr, "\t-L num-ports (default value 0). Run the mixed mode\n");
+ fprintf(stderr, "\t-S num-ports (default value 0). Run the mixed mode\n");
+ fprintf(stderr, "\t-D drain. If in client mode do a read following send.\n");
+ fprintf(stderr, "\t-T use SOCK_STREAM tcp-style sockets.\n");
+ fprintf(stderr, "\t-B add the specified address(es) as additional bind\n");
+ fprintf(stderr, "\t addresses of the local socket. Multiple addresses can\n");
+ fprintf(stderr, "\t be specified by using this argument multiple times.\n");
+ fprintf(stderr, "\t For example, '-B 10.0.0.1 -B 20.0.0.2'.\n");
+ fprintf(stderr, "\t In case of IPv6 linklocal address, interface name can be set in following way \n");
+ fprintf(stderr, "\t For example, '-B fe80::f8c3:b77f:698e:4506%%eth2'.\n");
+ fprintf(stderr, "\t-C use the specified address(es) for connection to the\n");
+ fprintf(stderr, "\t peer socket. Multiple addresses can be specified by\n");
+ fprintf(stderr, "\t using this argument multiple times.\n");
+ fprintf(stderr, "\t For example, '-C 10.0.0.1 -C 20.0.0.2'.\n");
+ fprintf(stderr, "\t This option is incompatible with the -h option.\n");
+ fprintf(stderr, "\t-O time to live (default value 0)\n");
+ fprintf(stderr, "\n");
+ fflush(stderr);
+
+} /* usage() */
+
+void *
+build_msg(int len)
+{
+ int i = len - 1;
+ int n;
+ char *msg_buf, *p;
+
+ msg_buf = malloc(len);
+ if (NULL == msg_buf) {
+ fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+ exit(1);
+ }
+ p = msg_buf;
+
+ do {
+ n = ((i > 50)?50:i);
+ memcpy(p, msg, ((i > 50)?50:i));
+ p += n;
+ i -= n;
+ } while (i > 0);
+
+ msg_buf[len-1] = '\0';
+
+ return(msg_buf);
+
+} /* build_msg() */
+
+static int
+print_cmsg(int type, sctp_cmsg_data_t *data)
+{
+ switch(type) {
+ case SCTP_INIT:
+ DEBUG_PRINT(DEBUG_MAX, "\tINIT\n");
+ if (DEBUG_MAX == debug_level) {
+ printf("\t\tsinit_num_ostreams=%d ",
+ data->init.sinit_num_ostreams);
+ printf("sinit_max_instreams=%d ",
+ data->init.sinit_max_instreams);
+ printf("sinit_max_attempts=%d ",
+ data->init.sinit_max_attempts);
+ printf("sinit_max_init_timeo=%d\n",
+ data->init.sinit_max_init_timeo);
+ }
+ break;
+ case SCTP_SNDRCV:
+ DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV");
+ if (DEBUG_MAX == debug_level) {
+ printf("(stream=%u ", data->sndrcv.sinfo_stream);
+ printf("ssn=%u ", data->sndrcv.sinfo_ssn);
+ printf("tsn=%u ", data->sndrcv.sinfo_tsn);
+ printf("flags=0x%x ", data->sndrcv.sinfo_flags);
+ printf("ppid=%u\n", data->sndrcv.sinfo_ppid);
+ printf("cumtsn=%u\n", data->sndrcv.sinfo_cumtsn);
+ }
+ break;
+ default:
+ DEBUG_PRINT(DEBUG_MIN, "\tUnknown type: %d\n", type);
+ break;
+ }
+ fflush(stdout);
+ return 0;
+
+} /* print_cmsg() */
+
+/* This function prints the message. */
+static int
+print_message(const int sk, struct msghdr *msg, size_t msg_len) {
+ struct cmsghdr *scmsg;
+ sctp_cmsg_data_t *data;
+ int i;
+
+ if (!(MSG_NOTIFICATION & msg->msg_flags)) {
+ int index = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "Data %zu bytes.", msg_len);
+ DEBUG_PRINT(DEBUG_MAX, " First %zu bytes: ",
+ (msg_len < BODYSIZE)?msg_len:BODYSIZE);
+ /* Make sure that everything is printable and that we
+ * are NUL terminated...
+ */
+ while ( msg_len > 0 ) {
+ char *text, tmptext[BODYSIZE];
+ int len;
+
+ memset(tmptext, 0x0, BODYSIZE);
+
+ text = msg->msg_iov[index].iov_base;
+ len = msg->msg_iov[index].iov_len;
+
+ if (msg_len == 1 && text[0] == 0) {
+ DEBUG_PRINT(DEBUG_MIN, "<empty> text[0]=%d",
+ text[0]);
+ break;
+ }
+
+ if ( len > msg_len ) {
+ /* text[(len = msg_len) - 1] = '\0'; */
+ text[(len = msg_len)] = '\0';
+ }
+
+ if ( (msg_len -= len) > 0 ) { index++; }
+
+ for (i = 0; i < len - 1; ++i) {
+ if (!isprint(text[i])) text[i] = '.';
+ }
+
+ strncpy(tmptext, text, BODYSIZE);
+ tmptext[BODYSIZE-1] = '\0';
+
+ DEBUG_PRINT(DEBUG_MAX, "%s", tmptext);
+ }
+
+ DEBUG_PRINT(DEBUG_MIN, "\n");
+ fflush(stdout);
+ } else { /* if(we have notification) */
+ struct sctp_assoc_change *sac;
+ struct sctp_send_failed *ssf;
+ struct sctp_paddr_change *spc;
+ struct sctp_remote_error *sre;
+ union sctp_notification *snp;
+ char addrbuf[INET6_ADDRSTRLEN];
+ const char *ap;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ int index = 0;
+
+ snp = (union sctp_notification *)msg->msg_iov[index].iov_base;
+
+ DEBUG_PRINT(DEBUG_MIN, "Notification:");
+
+ switch (snp->sn_header.sn_type) {
+ case SCTP_ASSOC_CHANGE:
+ sac = &snp->sn_assoc_change;
+ DEBUG_PRINT(DEBUG_MIN,
+ " SCTP_ASSOC_CHANGE(%s)\n",
+ sac_state_tbl[sac->sac_state]);
+ DEBUG_PRINT(DEBUG_MAX,
+ "\t\t(assoc_change: state=%hu, "
+ "error=%hu, instr=%hu "
+ "outstr=%hu)\n",
+ sac->sac_state, sac->sac_error,
+ sac->sac_inbound_streams,
+ sac->sac_outbound_streams);
+ break;
+ case SCTP_PEER_ADDR_CHANGE:
+ spc = &snp->sn_paddr_change;
+ DEBUG_PRINT(DEBUG_MIN,
+ " SCTP_PEER_ADDR_CHANGE\n");
+ if (spc->spc_aaddr.ss_family == AF_INET) {
+ sin = (struct sockaddr_in *)
+ &spc->spc_aaddr;
+ ap = inet_ntop(AF_INET, &sin->sin_addr,
+ addrbuf,
+ INET6_ADDRSTRLEN);
+ } else {
+ sin6 = (struct sockaddr_in6 *)
+ &spc->spc_aaddr;
+ ap = inet_ntop(AF_INET6,
+ &sin6->sin6_addr,
+ addrbuf,
+ INET6_ADDRSTRLEN);
+ }
+ DEBUG_PRINT(DEBUG_MAX,
+ "\t\t(peer_addr_change: %s "
+ "state=%d, error=%d)\n",
+ ap, spc->spc_state,
+ spc->spc_error);
+ break;
+ case SCTP_SEND_FAILED:
+ ssf = &snp->sn_send_failed;
+ DEBUG_PRINT(DEBUG_MIN,
+ " SCTP_SEND_FAILED\n");
+ DEBUG_PRINT(DEBUG_MAX,
+ "\t\t(sendfailed: len=%hu "
+ "err=%d)\n",
+ ssf->ssf_length, ssf->ssf_error);
+ break;
+ case SCTP_REMOTE_ERROR:
+ sre = &snp->sn_remote_error;
+ DEBUG_PRINT(DEBUG_MIN,
+ " SCTP_REMOTE_ERROR\n");
+ DEBUG_PRINT(DEBUG_MAX,
+ "\t\t(remote_error: err=%hu)\n",
+ ntohs(sre->sre_error));
+ break;
+ case SCTP_SHUTDOWN_EVENT:
+ DEBUG_PRINT(DEBUG_MIN,
+ " SCTP_SHUTDOWN_EVENT\n");
+ break;
+ default:
+ DEBUG_PRINT(DEBUG_MIN,
+ " Unknown type: %hu\n",
+ snp->sn_header.sn_type);
+ break;
+ }
+
+ fflush(stdout);
+ return 1;
+
+ } /* notification received */
+
+ for (scmsg = CMSG_FIRSTHDR(msg);
+ scmsg != NULL;
+ scmsg = CMSG_NXTHDR(msg, scmsg)) {
+
+ data = (sctp_cmsg_data_t *)CMSG_DATA(scmsg);
+ if (debug_level) print_cmsg(scmsg->cmsg_type, data);
+ }
+
+
+ fflush(stdout);
+ return 0;
+
+} /* print_message() */
+
+struct sockaddr *
+append_addr(const char *parm, struct sockaddr *addrs, int *ret_count)
+{
+ struct sockaddr *new_addrs = NULL;
+ void *aptr;
+ struct sockaddr *sa_addr;
+ struct sockaddr_in *b4ap;
+ struct sockaddr_in6 *b6ap;
+ struct hostent *hst4 = NULL;
+ struct hostent *hst6 = NULL;
+ int i4 = 0;
+ int i6 = 0;
+ int j;
+ int orig_count = *ret_count;
+ int count = orig_count;
+ char *ipaddr = strdup(parm);
+ char *ifname;
+ int ifindex = 0;
+
+ /* check the interface. */
+ ifname = strchr(ipaddr,'%');
+ if (ifname) {
+ *ifname=0;
+ ifname++;
+ ifindex = if_nametoindex(ifname);
+ if (!ifindex) {
+ fprintf(stderr, "bad interface name: %s\n", ifname);
+ goto finally;
+ }
+ }
+
+ /* Get the entries for this host. */
+ hst4 = gethostbyname(ipaddr);
+ hst6 = gethostbyname2(ipaddr, AF_INET6);
+
+ if ((NULL == hst4 || hst4->h_length < 1)
+ && (NULL == hst6 || hst6->h_length < 1)) {
+ fprintf(stderr, "bad hostname: %s\n", ipaddr);
+ goto finally;
+ }
+
+ /* Figure out the number of addresses. */
+ if (NULL != hst4) {
+ for (i4 = 0; NULL != hst4->h_addr_list[i4]; ++i4) {
+ count++;
+ }
+ }
+ if (NULL != hst6) {
+ for (i6 = 0; NULL != hst6->h_addr_list[i6]; ++i6) {
+ count++;
+ }
+ }
+
+ /* Expand memory for the new addresses. Assume all the addresses
+ * are v6 addresses.
+ */
+ new_addrs = (struct sockaddr *)
+ realloc(addrs, sizeof(struct sockaddr_in6) * count);
+
+ if (NULL == new_addrs) {
+ count = *ret_count;
+ goto finally;
+ }
+
+ /* Skip the existing addresses. */
+ aptr = new_addrs;
+ for (j = 0; j < orig_count; j++) {
+ sa_addr = (struct sockaddr *)aptr;
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ count = orig_count;
+ goto finally;
+ }
+ }
+
+ /* Put the new addresses away. */
+ if (NULL != hst4) {
+ for (j = 0; j < i4; ++j) {
+ b4ap = (struct sockaddr_in *)aptr;
+ memset(b4ap, 0x00, sizeof(*b4ap));
+ b4ap->sin_family = AF_INET;
+ b4ap->sin_port = htons(local_port);
+ bcopy(hst4->h_addr_list[j], &b4ap->sin_addr,
+ hst4->h_length);
+
+ aptr += sizeof(struct sockaddr_in);
+ } /* for (loop through the new v4 addresses) */
+ }
+
+ if (NULL != hst6) {
+ for (j = 0; j < i6; ++j) {
+ b6ap = (struct sockaddr_in6 *)aptr;
+ memset(b6ap, 0x00, sizeof(*b6ap));
+ b6ap->sin6_family = AF_INET6;
+ b6ap->sin6_port = htons(local_port);
+ b6ap->sin6_scope_id = if_index;
+ bcopy(hst6->h_addr_list[j], &b6ap->sin6_addr,
+ hst6->h_length);
+ if (!ifindex) {
+ b6ap->sin6_scope_id = ifindex;
+ }
+
+ aptr += sizeof(struct sockaddr_in6);
+ } /* for (loop through the new v6 addresses) */
+ }
+
+ finally:
+ free(ipaddr);
+ *ret_count = count;
+
+ return new_addrs;
+
+} /* append_addr() */
+
+int socket_r(void)
+{
+ struct sctp_event_subscribe subscribe;
+ int sk, error;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tsocket(%s, IPPROTO_SCTP)",
+ (socket_type == SOCK_SEQPACKET) ? "SOCK_SEQPACKET" : "SOCK_STREAM");
+
+ if ((sk = socket(s_loc.ss_family, socket_type, IPPROTO_SCTP)) < 0 ) {
+ if (do_exit) {
+ fprintf(stderr, "\n\n\t\t*** socket: failed to create"
+ " socket: %s ***\n",
+ strerror(errno));
+ exit(1);
+ } else {
+ return -1;
+ }
+ }
+ DEBUG_PRINT(DEBUG_MIN, " -> sk=%d\n", sk);
+
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ error = setsockopt(sk, SOL_SCTP, SCTP_EVENTS, (char *)&subscribe,
+ sizeof(subscribe));
+ if (error) {
+ fprintf(stderr, "SCTP_EVENTS: error: %d\n", error);
+ exit(1);
+ }
+ if (max_stream > 0) {
+ struct sctp_initmsg initmsg;
+ memset(&initmsg, 0, sizeof(struct sctp_initmsg));
+ initmsg.sinit_num_ostreams = max_stream;
+ error = setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg));
+ if (error) {
+ fprintf(stderr, "SCTP_INITMSG: error: %d\n", error);
+ exit(1);
+ }
+ }
+ return sk;
+
+} /* socket_r() */
+
+int bind_r(int sk, struct sockaddr_storage *saddr)
+{
+ int error = 0, i = 0;
+ char *host_s, *serv_s;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n\t\t*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n\t\t*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ do {
+ if (i > 0) sleep(1); /* sleep a while before new try... */
+
+ error = getnameinfo((struct sockaddr *)saddr, l_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV,
+ NI_NUMERICHOST);
+
+ if (error)
+ printf("%s\n", gai_strerror(error));
+
+ DEBUG_PRINT(DEBUG_MIN,
+ "\tbind(sk=%d, [a:%s,p:%s]) -- attempt %d/%d\n",
+ sk, host_s, serv_s, i+1, MAX_BIND_RETRYS);
+
+ error = bind(sk, (struct sockaddr *)saddr, l_len);
+
+ if (error != 0) {
+ if( errno != EADDRINUSE ) {
+ if (do_exit) {
+ fprintf(stderr, "\n\n\t\t***bind: can "
+ "not bind to %s:%s: %s ****\n",
+ host_s, serv_s,
+ strerror(errno));
+ exit(1);
+ } else {
+ return -1;
+ }
+ }
+ }
+ i++;
+ if (i >= MAX_BIND_RETRYS) {
+ fprintf(stderr, "Maximum bind() attempts. "
+ "Die now...\n\n");
+ exit(1);
+ }
+ } while (error < 0 && i < MAX_BIND_RETRYS);
+
+ free(host_s);
+ free(serv_s);
+ return 0;
+
+} /* bind_r() */
+
+int
+bindx_r(int sk, struct sockaddr *addrs, int count, int flag)
+{
+ int error;
+ int i;
+ struct sockaddr *sa_addr;
+ void *aptr;
+
+ /* Set the port in every address. */
+ aptr = addrs;
+ for (i = 0; i < count; i++) {
+ sa_addr = (struct sockaddr *)aptr;
+
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa_addr)->sin_port =
+ htons(local_port);
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa_addr)->sin6_port =
+ htons(local_port);
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ fprintf(stderr, "Invalid address family\n");
+ exit(1);
+ }
+ }
+
+ error = sctp_bindx(sk, addrs, count, flag);
+ if (error != 0) {
+ fprintf(stderr, "\n\n\t\t***bindx_r: error adding addrs:"
+ " %s. ***\n", strerror(errno));
+ exit(1);
+ }
+
+ return 0;
+
+} /* bindx_r() */
+
+int listen_r(int sk, int listen_count)
+{
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tlisten(sk=%d,backlog=%d)\n",
+ sk, listen_count);
+
+ /* Mark sk as being able to accept new associations */
+ error = listen(sk, listen_count);
+ if (error != 0) {
+ if (do_exit) {
+ fprintf(stderr, "\n\n\t\t*** listen: %s ***\n\n\n",
+ strerror(errno));
+ exit(1);
+ }
+ else return -1;
+ }
+ return 0;
+
+} /* listen_r() */
+
+int accept_r(int sk){
+ socklen_t len = 0;
+ int subsk;
+
+ DEBUG_PRINT(DEBUG_MIN, "\taccept(sk=%d)\n", sk);
+
+ subsk = accept(sk, NULL, &len);
+ if (subsk < 0) {
+ fprintf(stderr, "\n\n\t\t*** accept: %s ***\n\n\n", strerror(errno));
+ exit(1);
+ }
+
+ return subsk;
+} /* accept_r() */
+
+int connect_r(int sk, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tconnect(sk=%d)\n", sk);
+
+ /* Mark sk as being able to accept new associations */
+ error = connect(sk, serv_addr, addrlen);
+ if (error != 0) {
+ if (do_exit) {
+ fprintf(stderr, "\n\n\t\t*** connect: %s ***\n\n\n",
+ strerror(errno));
+ exit(1);
+ }
+ else return -1;
+ }
+ return 0;
+
+} /* connect_r() */
+
+int connectx_r(int sk, struct sockaddr *addrs, int count)
+{
+ int error;
+ int i;
+ struct sockaddr *sa_addr;
+ void *aptr;
+
+ /* Set the port in every address. */
+ aptr = addrs;
+ for (i = 0; i < count; i++) {
+ sa_addr = (struct sockaddr *)aptr;
+
+ switch(sa_addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa_addr)->sin_port =
+ htons(remote_port);
+ aptr += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa_addr)->sin6_port =
+ htons(remote_port);
+ aptr += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ fprintf(stderr, "Invalid address family\n");
+ exit(1);
+ }
+ }
+
+ error = sctp_connectx(sk, addrs, count, NULL);
+ if (error != 0) {
+ fprintf(stderr, "\n\n\t\t*** connectx_r: error connecting"
+ " to addrs: %s ***\n", strerror(errno));
+ exit(1);
+ }
+
+ return 0;
+
+} /* connectx_r() */
+
+int receive_r(int sk, int once)
+{
+ int recvsk = sk, i = 0, error = 0;
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ struct msghdr inmessage;
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+ exit(1);
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /* Get the messages sent */
+ while (1) {
+
+ if (recvsk == sk && socket_type == SOCK_STREAM &&
+ role == SERVER)
+ recvsk = accept_r(sk);
+
+ DEBUG_PRINT(DEBUG_MIN, "\trecvmsg(sk=%d) ", sk);
+
+ error = recvmsg(recvsk, &inmessage, MSG_WAITALL);
+ if (error < 0 && errno != EAGAIN) {
+ if (errno == ENOTCONN && socket_type == SOCK_STREAM &&
+ role == SERVER) {
+ printf("No association is present now!!\n");
+ close(recvsk);
+ recvsk = sk;
+ continue;
+ }
+
+ fprintf(stderr, "\n\t\t*** recvmsg: %s ***\n\n",
+ strerror(errno));
+ fflush(stdout);
+ if (do_exit) exit(1);
+ else goto error_out;
+ }
+ else if (error == 0) {
+ if (socket_type == SOCK_STREAM && role == SERVER) {
+ printf("No association is present now!!\n");
+ close(recvsk);
+ recvsk = sk;
+ continue;
+ }
+ printf("\n\t\trecvmsg() returned 0 !!!!\n");
+ fflush(stdout);
+ }
+
+ if (print_message(recvsk, &inmessage, error) > 0)
+ continue; /* got a notification... */
+
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ iov.iov_len = REALLY_BIG;
+ i++;
+ if (once)
+ break;
+ }
+
+ if (recvsk != sk)
+ close(recvsk);
+
+ free(iov.iov_base);
+ return 0;
+error_out:
+ close(sk);
+ free(iov.iov_base);
+ return -1;
+
+} /* receive_r () */
+
+int next_order(int state, int pattern)
+{
+ switch (pattern){
+ case ORDER_PATTERN_UNORDERED:
+ state = 0;
+ break;
+ case ORDER_PATTERN_ORDERED:
+ state = 1;
+ break;
+ case ORDER_PATTERN_ALTERNATE:
+ state = state ? 0 : 1;
+ break;
+ case ORDER_PATTERN_RANDOM:
+ state = rand() % 2;
+ break;
+ }
+
+ return state;
+}
+
+int next_stream(int state, int pattern)
+{
+ switch (pattern){
+ case STREAM_PATTERN_RANDOM:
+ state = rand() % (max_stream == 0 ? 1 : max_stream);
+ break;
+ case STREAM_PATTERN_SEQUENTIAL:
+ state = state + 1;
+ if (state >= max_stream)
+ state = 0;
+ break;
+ }
+
+ return state;
+}
+
+int next_msg_size(int msg_cnt)
+{
+ int msg_size;
+
+ if (size_arg) {
+ msg_size = size_arg;
+ } else if (test_case < NCASES) {
+ msg_size = msg_sizes[test_case][msg_cnt];
+ } else {
+ msg_size = (rand() % max_msgsize) + 1;
+ }
+
+ return msg_size;
+
+} /* next_msg_size() */
+
+int next_assoc(int i, int state, int pattern)
+{
+ int j;
+ int found = 0;
+ _assoc_state *as;
+
+
+ switch (pattern){
+ case ASSOC_PATTERN_RANDOM:
+ state = rand() % tosend;
+ break;
+ case ASSOC_PATTERN_SEQUENTIAL:
+ state = state + 1;
+ if (state >= tosend)
+ state = 0;
+ break;
+ }
+
+ as = poll_sks[i].assoc_state;
+ j = state;
+ do {
+ if (as[j].msg_sent < repeat_count) {
+ found = 1;
+ break;
+ }
+ if (++j >= tosend) {
+ j = 0;
+ }
+ } while (j != state);
+
+ if (found) {
+ return j;
+ } else {
+ return -1;
+ }
+
+} /* next_assoc() */
+
+int send_r(int sk, int stream, int order, int send_size, int assoc_i)
+{
+ int error = 0;
+ struct msghdr outmsg;
+ struct iovec iov;
+ char *message = NULL;
+ int msglen = 0;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+
+ if (send_size > 0) {
+ message = build_msg(send_size);
+ msglen = strlen(message) + 1;
+ iov.iov_base = message;
+ iov.iov_len = msglen;
+ }
+ else {
+ if (do_exit) {
+ exit(1);
+ } else {
+ goto error_out;
+ }
+ }
+
+ outmsg.msg_name = &s_rem;
+ outmsg.msg_namelen = sizeof(struct sockaddr_storage);
+ outmsg.msg_iov = &iov;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = outcmsg;
+ outmsg.msg_controllen = sizeof(outcmsg);
+ outmsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmsg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ outmsg.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_ppid = rand();
+ sinfo->sinfo_stream = stream;
+ sinfo->sinfo_flags = 0;
+ if (!order)
+ sinfo->sinfo_flags = SCTP_UNORDERED;
+ if (timetolive)
+ sinfo->sinfo_timetolive = timetolive;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",
+ sk, assoc_i, send_size);
+ DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV");
+ if (DEBUG_MAX == debug_level) {
+ printf("(stream=%u ", sinfo->sinfo_stream);
+ printf("flags=0x%x ", sinfo->sinfo_flags);
+ printf("ppid=%u\n", sinfo->sinfo_ppid);
+ }
+
+ /* Send to our neighbor. */
+ error = sendmsg(sk, &outmsg, MSG_WAITALL);
+ if (error != msglen) {
+ fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",
+ strerror(errno));
+ fflush(stdout);
+
+ if (do_exit) {
+ exit(1);
+ } else {
+ if (!drain)
+ goto error_out;
+ }
+ }
+
+ if (send_size > 0) free(message);
+ return 0;
+error_out:
+ if (send_size > 0) free(message);
+ return -1;
+
+} /* send_r() */
+
+int close_r(int sk)
+{
+ int error = 0;
+
+ DEBUG_PRINT(DEBUG_MIN, "\tclose(sk=%d)\n",sk);
+
+ error = close(sk);
+ if (error != 0) {
+ if (do_exit) {
+ fprintf(stderr, "\n\n\t\t*** close: %s ***\n\n",
+ strerror(errno));
+ exit(1);
+ } else {
+ return -1;
+ }
+ }
+ fflush(stdout);
+ return 0;
+
+} /* close_r() */
+
+void
+server(int sk)
+{
+ if (max_msgsize > DEFAULT_MAX_WINDOW) {
+ if (setsockopt(sk, SOL_SOCKET, SO_RCVBUF, &max_msgsize,
+ sizeof(max_msgsize)) < 0) {
+ perror("setsockopt(SO_RCVBUF)");
+ exit(1);
+ }
+ }
+
+ receive_r(sk, 0);
+
+} /* server() */
+
+void
+client(int sk)
+{
+ int msg_size;
+ int i;
+
+ for (i = 0; i < msg_cnt; i++) {
+
+ msg_size = next_msg_size(i);
+ order_state = next_order(order_state, order_pattern);
+ stream_state = next_stream(stream_state, stream_pattern);
+
+ if (send_r(sk, stream_state, order_state, msg_size, 0) < 0)
+ break;
+ /* The sender is echoing so do discard the echoed data. */
+ if (drain) {
+ receive_r(sk, 1);
+ }
+ }
+} /* client() */
+
+void
+mixed_mode_test(void)
+{
+ int error, i, j, max_fd, sks, size;
+ int assoc_i, n_msg_size, n_order, n_stream;
+ int done = 0;
+ fd_set *ibitsp = NULL, *obitsp = NULL, *xbitsp = NULL;
+ char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
+ struct iovec iov;
+ struct msghdr inmessage;
+ _assoc_state *as;
+
+
+ /* Set up the listeners. If listeners is 0, set up one socket for
+ * transmitting only.
+ */
+ iov.iov_base = NULL;
+ max_fd = -1;
+ sks = (0 == listeners) ? 1 : listeners;
+ memset(poll_sks, 0, sks * sizeof(_poll_sks));
+
+ for (i = 0; i < sks; i++) {
+ poll_sks[i].sk = socket_r();
+
+ if (s_loc.ss_family == AF_INET6)
+ ( (struct sockaddr_in6 *)&s_loc)->sin6_port =
+ htons(local_port + i);
+ else
+ ( (struct sockaddr_in *)&s_loc)->sin_port =
+ htons(local_port + i);
+
+ bind_r(poll_sks[i].sk, &s_loc);
+ if (listeners) {
+ listen_r(poll_sks[i].sk, 100);
+ }
+ if (max_msgsize > DEFAULT_MAX_WINDOW) {
+ if (setsockopt(poll_sks[i].sk, SOL_SOCKET, SO_RCVBUF,
+ &max_msgsize, sizeof(max_msgsize)) < 0) {
+ perror("setsockopt(SO_RCVBUF)");
+ exit(1);
+ }
+ }
+
+ if (tosend) {
+ if ((poll_sks[i].assoc_state = (_assoc_state *)malloc(
+ sizeof(_assoc_state) * tosend)) == NULL) {
+ printf("Can't allocate memory.\n");
+ goto clean_up;
+ }
+ memset(poll_sks[i].assoc_state, 0,
+ sizeof(_assoc_state) * tosend);
+ }
+
+ if (poll_sks[i].sk > max_fd) {
+ max_fd = poll_sks[i].sk;
+ }
+ }
+
+ size = howmany(max_fd + 1, NFDBITS) * sizeof(fd_mask);
+ if ((ibitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("Can't allocate memory.\n");
+ goto clean_up;
+ }
+ if ((obitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("Can't allocate memory.\n");
+ goto clean_up;
+ }
+ if ((xbitsp = (fd_set *)malloc(size)) == NULL) {
+ printf("Can't allocate memory.\n");
+ goto clean_up;
+ }
+
+ memset(ibitsp, 0, size);
+ memset(obitsp, 0, size);
+ memset(xbitsp, 0, size);
+
+
+ /* Initialize inmessage with enough space for DATA... */
+ memset(&inmessage, 0, sizeof(inmessage));
+ if ((iov.iov_base = malloc(REALLY_BIG)) == NULL) {
+ fprintf(stderr, "\n\t\t*** malloc not enough memory!!! ***\n");
+ goto clean_up;
+ }
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ /* or a control message. */
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /* Set up the remote port number per association for output. */
+ for (i = 0; i < sks; i++) {
+ as = poll_sks[i].assoc_state;
+ for (j = 0; j < tosend; j++) {
+ as[j].rem_port = remote_port + j;
+ }
+ }
+
+ while (!done) {
+
+ for (i = 0; i < sks; i++) {
+ FD_SET(poll_sks[i].sk, ibitsp);
+ FD_SET(poll_sks[i].sk, obitsp);
+ FD_SET(poll_sks[i].sk, xbitsp);
+ }
+ if ((error = select(max_fd + 1, ibitsp, obitsp, xbitsp,
+ (struct timeval *)0)) < 0) {
+ fprintf(stderr, "\n\t\t*** select() failed ");
+ fprintf(stderr, "with error: %s\n\n",
+ strerror(errno));
+ fflush(stdout);
+ goto clean_up;
+ }
+
+ for (i = 0; i < sks; i++) {
+ /* Is there anything to read from the socket? */
+ if (listeners && FD_ISSET(poll_sks[i].sk, ibitsp)) {
+
+ FD_CLR(poll_sks[i].sk, ibitsp);
+ error = recvmsg(poll_sks[i].sk, &inmessage,
+ MSG_WAITALL);
+ if (error < 0) {
+ fprintf(stderr,
+ "\n\t\t*** recvmsg: %s ***\n\n",
+ strerror(errno));
+ fflush(stdout);
+ goto clean_up;
+ }
+ else if (error == 0) {
+ printf("\n\t\trecvmsg() returned ");
+ printf("0 !!!!\n");
+ fflush(stdout);
+ }
+
+ print_message(poll_sks[i].sk, &inmessage,
+ error);
+
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ iov.iov_len = REALLY_BIG;
+ }
+
+ /* Is this socket writeable? */
+ if (tosend && FD_ISSET(poll_sks[i].sk, obitsp)) {
+
+ FD_CLR(poll_sks[i].sk, obitsp);
+
+ /* Pick an association. */
+ assoc_i = next_assoc(i, poll_sks[i].assoc_i,
+ assoc_pattern);
+ if (assoc_i < 0) {
+ /* No work to do on any associations.
+ * We are probably done. */
+ if (!listeners) {
+ done = 1;
+ }
+ continue;
+ }
+ poll_sks[i].assoc_i = assoc_i;
+
+ as = poll_sks[i].assoc_state;
+ n_msg_size = next_msg_size(as[assoc_i].msg_cnt);
+ n_order = as[assoc_i].order_state =
+ next_order(as[assoc_i].order_state,
+ order_pattern);
+ n_stream = as[assoc_i].stream_state =
+ next_stream(as[assoc_i].stream_state,
+ stream_pattern);
+
+ /* Set the destination port. */
+ if (s_rem.ss_family == AF_INET6)
+ ( (struct sockaddr_in6 *)&s_rem)->
+ sin6_port =
+ htons(as[assoc_i].rem_port);
+ else
+ ( (struct sockaddr_in *)&s_rem)->
+ sin_port =
+ htons(as[assoc_i].rem_port);
+
+ /* Send a message thru the association. */
+ if (send_r(poll_sks[i].sk, n_stream, n_order,
+ n_msg_size, assoc_i) < 0) {
+ /* Don't increment counter if there
+ * is a problem of sending.
+ */
+ continue;
+ }
+
+ /* Increment counters. */
+ if (++as[assoc_i].msg_cnt >= MSG_CNT) {
+ as[assoc_i].msg_cnt = 0;
+ }
+ if (++as[assoc_i].msg_sent >=
+ repeat_count) {
+ fprintf(stderr, "Association #%d in ",
+ assoc_i);
+ fprintf(stderr, "sk=%d has ",
+ poll_sks[i].sk);
+ fprintf(stderr, "completed %d msg as ",
+ as[assoc_i].msg_sent);
+ fprintf(stderr, "cycle %d.\n",
+ ++as[assoc_i].cycle);
+
+ /* In the mixed mode, -x not only
+ * specify the longer repeat cycle,
+ * but it also mean to run the test
+ * forever.
+ */
+ if (xflag) {
+ as[assoc_i].msg_sent = 0;
+ }
+
+ }
+
+ }
+ }
+ }
+
+clean_up:
+ for (i = 0; i < sks; i++) {
+ close(poll_sks[i].sk);
+ if (poll_sks[i].assoc_state) {
+ free(poll_sks[i].assoc_state);
+ }
+ }
+
+ if (ibitsp) free(ibitsp);
+ if (obitsp) free(obitsp);
+ if (xbitsp) free(xbitsp);
+
+ if (iov.iov_base) free(iov.iov_base);
+
+} /* mixed_mode_test() */
+
+void start_test(int role)
+{
+ int sk;
+ int i = 0;
+
+ DEBUG_PRINT(DEBUG_NONE, "\nStarting tests...\n");
+
+ repeat_count = repeat;
+
+
+ if (MIXED == role) {
+ repeat_count = repeat_count * msg_cnt; /* Repeat per assoc. */
+ mixed_mode_test();
+ return;
+ }
+
+ sk = socket_r();
+ if (sk < 0) {
+ DEBUG_PRINT(DEBUG_NONE, "\nSocket create err %d\n", errno);
+ return;
+ }
+
+ if (bind_r(sk, &s_loc) == -1) {
+ DEBUG_PRINT(DEBUG_NONE, "\nSocket bind err %d\n", errno);
+ return;
+ }
+
+ /* Do we need to do bindx() to add any additional addresses? */
+ if (bindx_add_addrs)
+ bindx_r(sk, bindx_add_addrs, bindx_add_count,
+ SCTP_BINDX_ADD_ADDR);
+
+ if (role == SERVER) {
+ listen_r(sk, 100);
+ } else {
+ if (socket_type == SOCK_STREAM && connectx_count == 0)
+ connect_r(sk, (struct sockaddr *)&s_rem, r_len);
+
+ if (connectx_count != 0)
+ connectx_r(sk, connectx_addrs, connectx_count);
+ }
+
+ if (!debug_level) {
+ printf(" ");
+ }
+
+ for(i = 0; i < repeat_count; i++) {
+
+ if (role == SERVER) {
+ DEBUG_PRINT(DEBUG_NONE,
+ "Server: Receiving packets.\n");
+ server(sk);
+ } else {
+ DEBUG_PRINT(DEBUG_NONE,
+ "Client: Sending packets.(%d/%d)\n",
+ i+1, repeat_count);
+ client(sk);
+ }
+
+ fflush(stdout);
+ }
+
+ close_r(sk);
+
+} /* start_test() */
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ char *interface = NULL;
+ struct sockaddr_in *t_addr;
+ struct sockaddr_in6 *t_addr6;
+ struct sockaddr *tmp_addrs = NULL;
+
+ /* Parse the arguments. */
+ while ((c = getopt(argc, argv, ":H:L:P:S:a:h:p:c:d:lm:sx:X:o:t:M:r:w:Di:TB:C:O:")) >= 0 ) {
+
+ switch (c) {
+ case 'H':
+ local_host = optarg;
+ break;
+ case 'L':
+ role = MIXED;
+ listeners = atoi(optarg);
+ if (listeners > MAX_POLL_SKS) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 'S':
+ role = MIXED;
+ tosend = atoi(optarg);
+ if (tosend > MAX_POLL_SKS) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'a':
+ assoc_pattern = atoi(optarg);
+ if (assoc_pattern < ASSOC_PATTERN_SEQUENTIAL
+ || assoc_pattern > ASSOC_PATTERN_RANDOM ) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 'D':
+ drain = 1;
+ do_exit = 0;
+ break;
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ case 's':
+ if (role != NOT_DEFINED) {
+ printf("%s: only -s or -l\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ role = CLIENT;
+ break;
+ case 'l':
+ if (role != NOT_DEFINED) {
+ printf("%s: only -s or -l\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ role = SERVER;
+ break;
+ case 'd':
+ debug_level = atoi(optarg);
+ if (debug_level < DEBUG_NONE
+ || debug_level > DEBUG_MAX) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'x':
+ repeat = atoi(optarg);
+ if (!repeat) {
+ xflag = 1;
+ repeat = BIG_REPEAT;
+ }
+ break;
+ case 'X':
+ msg_cnt = atoi(optarg);
+ if ((msg_cnt <= 0) || (msg_cnt > MSG_CNT)) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'c':
+ test_case = atoi(optarg);
+ if (test_case > NCASES) {
+ usage(argv[0]);
+ exit(1);
+ }
+ if (test_case < 0) {
+ size_arg = -test_case;
+ }
+
+ break;
+ case 'o':
+ order_pattern = atoi(optarg);
+ if (order_pattern < ORDER_PATTERN_UNORDERED
+ || order_pattern > ORDER_PATTERN_RANDOM ) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'O':
+ timetolive = atoi(optarg);
+ if (timetolive < 0) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 't':
+ stream_pattern = atoi(optarg);
+ if (stream_pattern < STREAM_PATTERN_SEQUENTIAL
+ || stream_pattern > STREAM_PATTERN_RANDOM ) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'M':
+ max_stream = atoi(optarg);
+ if (max_stream < 0
+ || max_stream >= (1<<16)) {
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'r':
+ seed = atoi(optarg);
+ break;
+ case 'm':
+ max_msgsize = atoi(optarg);
+#if 0
+ if ((max_msgsize < DEFAULT_MIN_WINDOW) ||
+ (max_msgsize > 65515)) {
+ usage(argv[0]);
+ exit(1);
+ }
+#endif
+ break;
+ case 'i':
+ interface = optarg;
+ if_index = if_nametoindex(interface);
+ if (!if_index) {
+ printf("Interface %s unknown\n", interface);
+ exit(1);
+ }
+ break;
+ case 'T':
+ socket_type = SOCK_STREAM;
+ break;
+ case 'B':
+ tmp_addrs = append_addr(optarg, bindx_add_addrs,
+ &bindx_add_count);
+ if (NULL == tmp_addrs) {
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", optarg);
+ exit(1);
+ }
+ bindx_add_addrs = tmp_addrs;
+ break;
+ case 'C':
+ tmp_addrs = append_addr(optarg, connectx_addrs,
+ &connectx_count);
+ if (NULL == tmp_addrs) {
+ fprintf(stderr, "No memory to add ");
+ fprintf(stderr, "%s\n", optarg);
+ exit(1);
+ }
+ connectx_addrs = tmp_addrs;
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ exit(0);
+ }
+ } /* while() */
+
+ if (NOT_DEFINED == role) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+
+ if (SERVER == role && NULL == local_host && remote_host != NULL) {
+ fprintf (stderr, "%s: Server needs local address, "
+ "not remote address\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ if (CLIENT == role && NULL == remote_host && connectx_count == 0) {
+ fprintf (stderr, "%s: Client needs at least remote address "
+ "& port\n", argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ if (MIXED == role) {
+ if (listeners && NULL == local_host) {
+ fprintf (stderr, "%s: Servers need local address\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+ if (tosend && NULL == remote_host) {
+ fprintf (stderr, "%s: Clients need remote address ",
+ argv[0]);
+ fprintf (stderr, "& port\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "%s: non-option arguments are illegal: ",
+ argv[0]);
+ while (optind < argc)
+ fprintf(stderr, "%s ", argv[optind++]);
+ fprintf (stderr, "\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (remote_host != NULL && connectx_count != 0) {
+ fprintf(stderr, "%s: You can not provide both -h and -C options.\n",
+ argv[0]);
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (remote_host != NULL && remote_port != 0) {
+ struct addrinfo *res;
+ int error;
+ char *host_s, *serv_s;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ error = getaddrinfo(remote_host, 0, NULL, &res);
+ if (error) {
+ printf("%s.\n", gai_strerror(error));
+ usage(argv[0]);
+ exit(1);
+ }
+
+ switch (res->ai_family) {
+ case AF_INET:
+ t_addr = (struct sockaddr_in *)&s_rem;
+
+ memcpy(t_addr, res->ai_addr,
+ res->ai_addrlen);
+ t_addr->sin_family = res->ai_family;
+ t_addr->sin_port = htons(remote_port);
+
+ r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr->sin_len = r_len;
+#endif
+ break;
+ case AF_INET6:
+
+ t_addr6 = (struct sockaddr_in6 *)&s_rem;
+
+ memcpy(t_addr6, res->ai_addr,
+ res->ai_addrlen);
+ t_addr6->sin6_family = res->ai_family;
+ t_addr6->sin6_port = htons(remote_port);
+ if (interface)
+ t_addr6->sin6_scope_id =
+ if_nametoindex(interface);
+
+ r_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr6->sin6_len = r_len;
+#endif
+ break;
+ }
+
+ getnameinfo((struct sockaddr *)&s_rem, r_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+ DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n",
+ host_s, serv_s, res->ai_family);
+
+ freeaddrinfo(res);
+ }
+
+ if (connectx_count != 0) {
+ switch (connectx_addrs->sa_family) {
+ case AF_INET:
+ t_addr = (struct sockaddr_in *)&s_rem;
+ r_len = sizeof(struct sockaddr_in);
+ memcpy(t_addr, connectx_addrs, r_len);
+ t_addr->sin_port = htons(remote_port);
+ break;
+ case AF_INET6:
+ t_addr6 = (struct sockaddr_in6 *)&s_rem;
+ r_len = sizeof(struct sockaddr_in6);
+ memcpy(t_addr6, connectx_addrs, r_len);
+ t_addr6->sin6_port = htons(remote_port);
+ break;
+ }
+ }
+
+ if (local_host != NULL) {
+ struct addrinfo *res;
+ int error;
+ char *host_s, *serv_s;
+ struct sockaddr_in *t_addr;
+ struct sockaddr_in6 *t_addr6;
+
+ if ((host_s = malloc(NI_MAXHOST)) == NULL) {
+ fprintf(stderr, "\n*** host_s malloc failed!!! ***\n");
+ exit(1);
+ }
+ if ((serv_s = malloc(NI_MAXSERV)) == NULL) {
+ fprintf(stderr, "\n*** serv_s malloc failed!!! ***\n");
+ exit(1);
+ }
+
+ if (strcmp(local_host, "0") == 0)
+ local_host = "0.0.0.0";
+
+ error = getaddrinfo(local_host, 0, NULL, &res);
+ if (error) {
+ printf("%s.\n", gai_strerror(error));
+ usage(argv[0]);
+ exit(1);
+ }
+
+ switch (res->ai_family) {
+ case AF_INET:
+ t_addr = (struct sockaddr_in *)&s_loc;
+ memcpy(t_addr, res->ai_addr,
+ res->ai_addrlen);
+ t_addr->sin_family = res->ai_family;
+ t_addr->sin_port = htons(local_port);
+
+ l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr->sin_len = l_len;
+#endif
+ break;
+ case AF_INET6:
+ t_addr6 = (struct sockaddr_in6 *)&s_loc;
+
+ memcpy(t_addr6, res->ai_addr,
+ res->ai_addrlen);
+ t_addr6->sin6_family = res->ai_family;
+ t_addr6->sin6_port = htons(local_port);
+ if (interface)
+ t_addr6->sin6_scope_id =
+ if_nametoindex(interface);
+
+ l_len = res->ai_addrlen;
+
+#ifdef __FreeBSD__
+ t_addr6->sin6_len = l_len;
+#endif
+ break;
+ }
+
+ error = getnameinfo((struct sockaddr *)&s_loc, l_len, host_s,
+ NI_MAXHOST, serv_s, NI_MAXSERV, NI_NUMERICHOST);
+
+ if (error)
+ printf("%s..\n", gai_strerror(error));
+
+ DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n",
+ host_s, serv_s, res->ai_family);
+
+ freeaddrinfo(res);
+ }
+
+
+ /* A half-hearted attempt to seed rand() */
+ if (seed == 0 ) {
+ seed = time(0);
+ DEBUG_PRINT(DEBUG_NONE, "seed = %d\n", seed);
+ }
+
+ srand(seed);
+
+ /* Let the testing begin. */
+ start_test(role);
+
+ return 0;
+
+} /* main() */
diff --git a/src/apps/sctp_xconnect.c b/src/apps/sctp_xconnect.c
new file mode 100644
index 0000000..6759c0e
--- /dev/null
+++ b/src/apps/sctp_xconnect.c
@@ -0,0 +1,579 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Ryan Layer <rmlayer@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <netdb.h>
+#include <getopt.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAXHOSTNAME 64
+
+#define MAXCLIENTNUM 10000
+
+#define TRUE 1
+
+#define SERVER 1
+#define CLIENT 0
+#define NOT_DEFINED -1
+
+int mode = NOT_DEFINED;
+
+int assoc_num,
+ remote_port,
+ local_port;
+int active = 0;
+
+char *local_host = NULL;
+char *remote_host = NULL;
+sockaddr_storage_t client_loop,
+ server_loop;
+struct hostent *hst;
+char big_buffer[REALLY_BIG];
+
+void usage(char *argv0);
+void parse_arguments(int argc, char*argv[]);
+void data_received(struct msghdr *inmessage, int len, int stream,
+ int server_socket);
+int event_received(struct msghdr *inmessage, int assoc_num);
+void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds);
+void server_mode(void);
+void client_mode(void);
+
+/* Print the syntax/usage */
+void usage(char *argv0)
+{
+ printf("usage: %s -H localhost -P localport -l|c [-h remotehost]\n"
+ "\t\t[-p remoteport] [-a] [-n <cnt>]\n"
+ " -H\t\tspecify a local address.\n"
+ " -P\t\tspecify the local port number to be used\n"
+ " -l\t\trun in server mode.\n"
+ " -c\t\trun in client mode.\n"
+ " -h\t\tspecify the peer address.\n"
+ " -p\t\tspecify the port number for the peer address.\n"
+ " -a\t\tactively generate traffic with the server.\n"
+ " -n\t\tspecify the number of associations to create.\n",
+ argv0);
+}
+
+/* Parse command line options */
+void parse_arguments(int argc, char*argv[]) {
+ int c;
+
+ while ((c = getopt(argc, argv, ":H:P:ach:ln:p:")) >= 0) {
+ switch (c) {
+ case 'H':
+ local_host = optarg;
+ break;
+ case 'P':
+ local_port = atoi(optarg);
+ break;
+ case 'c':
+ if (mode == NOT_DEFINED)
+ mode = CLIENT;
+ else {
+ usage(argv[0]);
+ exit(0);
+ }
+ break;
+ case 'a':
+ active = 1;
+ break;
+ case 'h':
+ remote_host = optarg;
+ break;
+ case 'l':
+ if (mode == NOT_DEFINED)
+ mode = SERVER;
+ else {
+ usage(argv[0]);
+ exit(0);
+ }
+ break;
+ case 'n':
+ assoc_num = atoi(optarg);
+ break;
+ case 'p':
+ remote_port = atoi(optarg);
+ break;
+ default:
+ usage(argv[0]);
+ exit(0);
+ }
+ } /* while() */
+
+ if (mode == CLIENT) {
+ if (assoc_num) {
+ if (assoc_num > MAXCLIENTNUM) {
+ printf("The number of associations indicated "
+ "is greater than the");
+ printf("max number of associations "
+ "allowed(%d).", MAXCLIENTNUM);
+ usage(argv[0]);
+ exit(0);
+ }
+ } else
+ assoc_num = 1;
+
+ if (remote_host && remote_port) {
+ hst = gethostbyname(remote_host);
+
+ memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0],
+ sizeof(server_loop.v4.sin_addr));
+
+ server_loop.v4.sin_family = AF_INET;
+server_loop.v4.sin_port = htons(remote_port);
+ } else {
+ printf("Remote host and remote port must be defined "
+ "in client mode\n");
+ usage(argv[0]);
+ exit(0);
+ }
+
+ if (local_host) {
+ hst = gethostbyname(local_host);
+
+ memcpy(&client_loop.v4.sin_addr, hst->h_addr_list[0],
+ sizeof(client_loop.v4.sin_addr));
+ } else
+ client_loop.v4.sin_addr.s_addr = INADDR_ANY;
+
+ if (local_port)
+ client_loop.v4.sin_port = htons(local_port);
+ else
+ client_loop.v4.sin_port = 0;
+
+ client_loop.v4.sin_family = AF_INET;
+ } else if (mode == SERVER) {
+ if (active) {
+ printf("This option if for client use only");
+ usage(argv[0]);
+ exit(0);
+ }
+
+ if (remote_host || remote_port) {
+ printf("Remote values not needed in server mode.\n");
+ usage(argv[0]);
+ exit(0);
+ }
+
+ if (local_host) {
+ hst = gethostbyname(local_host);
+
+ memcpy(&server_loop.v4.sin_addr, hst->h_addr_list[0],
+ sizeof(server_loop.v4.sin_addr));
+ } else
+ server_loop.v4.sin_addr.s_addr = INADDR_ANY;
+
+ if (local_port)
+ server_loop.v4.sin_port = htons(local_port);
+ else {
+ printf("Specify a local port in server mode.\n");
+ usage(argv[0]);
+ exit(0);
+ }
+
+ server_loop.v4.sin_family = AF_INET;
+ } else {
+ printf("Must assisgn a client or server mode.\n");
+ usage(argv[0]);
+ exit(0);
+ }
+} /* parse_arguments() */
+
+/* Handle data received */
+void data_received(struct msghdr *inmessage, int len, int stream, int socket) {
+
+ int ppid, error;
+ char *ping = "PING";
+
+ if (mode == SERVER) {
+ ppid = rand();
+
+ error = sctp_sendmsg(socket,
+ inmessage->msg_iov->iov_base,
+ len,
+ (struct sockaddr *)inmessage->msg_name,
+ inmessage->msg_namelen,
+ ppid,
+ 0,
+ stream,
+ 0, 0);
+
+ if (error < 0) {
+ printf("Send Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+ } else {
+ ppid = rand();
+
+ printf("Data Received by socket #: %d.\n", socket);
+ printf("\tMessage = %s\n",
+ (char *)inmessage->msg_iov->iov_base);
+
+ if (active) {
+ error = sctp_sendmsg(socket, ping, strlen(ping) + 1,
+ (struct sockaddr *)&server_loop,
+ sizeof(server_loop), ppid, 0,
+ stream, 0, 0);
+ if (error < 0) {
+ printf("Send Failure: %s.\n",
+ strerror(errno));
+ DUMP_CORE;
+ }
+ }
+ }
+}
+
+/* This will print what type of SCTP_ASSOC_CHANGE state that was received */
+void print_sctp_sac_state(struct msghdr *msg) {
+
+ char *data;
+ union sctp_notification *sn;
+
+ if (msg->msg_flags & MSG_NOTIFICATION) {
+ data = (char *)msg->msg_iov[0].iov_base;
+
+ sn = (union sctp_notification *)data;
+
+ switch (sn->sn_assoc_change.sac_state) {
+ case SCTP_COMM_UP:
+ printf("SCTP_COMM_UP\n");
+ break;
+ case SCTP_COMM_LOST:
+ printf("SCTP_COMM_LOST\n");
+ break;
+ case SCTP_RESTART:
+ printf("SCTP_RESTART");
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ printf("SCTP_SHUTDOWN_COMP\n");
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ printf("SCTP_CANT_STR_ASSOC\n");
+ break;
+ default:
+ break;
+ }
+ }
+} /* void print_sctp_sac_state() */
+
+/* Tests what type of MSG_NOTIFICATION has been received.
+* For now this fucntion only works with SCTP_ASSOC_CHANGE
+* types, but can be easily expanded.
+*
+* Will return...
+* -1 if the msg_flags is not MSG_NOTIFICATION
+* 0 if the MSG_NOTIFICATION type differs from the type
+* passed into the additional variable
+* 1 if the MSG_NOTIFICATION type matches the type
+* passed into the additional variable
+*/
+int test_check_notification_type(struct msghdr *msg,
+ uint16_t sn_type,
+ uint32_t additional) {
+
+ char *data;
+ union sctp_notification *sn;
+
+ if (!(msg->msg_flags & MSG_NOTIFICATION)) {
+ return -1;
+ } else {
+
+ /* Fixup for testframe. */
+ data = (char *)msg->msg_iov[0].iov_base;
+
+ sn = (union sctp_notification *)data;
+
+ if (sn->sn_header.sn_type != sn_type)
+ return 0;
+ else if (sn->sn_header.sn_type == SCTP_ASSOC_CHANGE)
+ if (sn->sn_assoc_change.sac_state == additional)
+ return 1;
+ return 0;
+ }
+}
+
+/* Determine the type of event and make correct adjustments to the
+* association count
+*/
+int event_received(struct msghdr *inmessage, int assoc_num) {
+
+ int error;
+
+ printf("Event Received\n");
+
+ print_sctp_sac_state(inmessage);
+
+ if (mode == SERVER) {
+ /* Test type of Event */
+ error = test_check_notification_type(inmessage,
+ SCTP_ASSOC_CHANGE,
+ SCTP_COMM_UP);
+ if (error > 0) {
+ assoc_num++;
+ printf("Assosiation Established: count = %d.\n",
+ assoc_num);
+ } else {
+ error = test_check_notification_type(inmessage,
+ SCTP_ASSOC_CHANGE,
+ SCTP_SHUTDOWN_COMP);
+
+ if (error > 0) {
+ assoc_num--;
+ printf("Assosiation Shutdown: count = %d.\n",
+ assoc_num);
+ }
+ }
+ }
+ return assoc_num;
+}
+
+void server_mode() {
+ sockaddr_storage_t msgname;
+ int server_socket,
+ error,
+ stream;
+ int assoc_num =0;
+ struct msghdr inmessage;
+ struct iovec iov;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+
+
+ printf("Running in Server Mode...\n");
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen =1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof (msgname);
+
+ stream = 1;
+
+ server_socket = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ if (server_socket < 0) {
+ printf("Socket Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+
+ error = bind(server_socket, &server_loop.sa, sizeof(server_loop));
+ if (error != 0 ) {
+ printf("Bind Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+
+ error = listen(server_socket, 1);
+ if (error != 0) {
+ printf("Listen Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+ while (TRUE) {
+ error = recvmsg(server_socket, &inmessage, MSG_WAITALL);
+ if (error < 0) {
+ printf("Receive Failure: %s\n",
+ strerror(errno));
+ } else {
+ if (inmessage.msg_flags & MSG_NOTIFICATION)
+ assoc_num = event_received(&inmessage, assoc_num);
+ else
+ data_received(&inmessage, error, stream, server_socket);
+ }
+ }
+}
+
+void client_mode() {
+
+ int i, error, stream, max_socket = 0;
+ uint32_t ppid = 0;
+ int client_socket[assoc_num];
+ char *message = "Awake";
+ fd_set rfds;
+ struct timeval tv;
+
+ stream = 1;
+
+ printf("Running in Client Mode...\n");
+
+ /* Create the sockets */
+ for (i = 0; i < assoc_num; i++) {
+ client_socket[i] = socket(PF_INET, SOCK_SEQPACKET,
+ IPPROTO_SCTP);
+ if (client_socket[i] < 0 ){
+ printf("Socket Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+
+ if (local_port) {
+ error = bind(client_socket[i], &client_loop.sa,
+ sizeof(client_loop));
+ if (error < 0) {
+ printf("Bind Failure: %s\n", strerror(errno));
+ DUMP_CORE;
+ }
+ }
+
+ printf("Create Socket #: %d\n", client_socket[i]);
+
+ /* Connect to server and send initial message */
+ error = connect(client_socket[i], &server_loop.sa,
+ sizeof(server_loop));
+ if (error < 0){
+ printf("Connect Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+
+ max_socket = client_socket[i];
+
+ ppid++;
+
+ /* Send initial message */
+ error = sctp_sendmsg(client_socket[i],
+ message,
+ strlen(message) + 1,
+ (struct sockaddr *)&server_loop,
+ sizeof(server_loop),
+ ppid,
+ 0,
+ stream,
+ 0, 0);
+ if (error < 0 ) {
+ printf("Send Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ }
+ }
+
+ while (TRUE){
+
+ /* Clear the set for select() */
+ FD_ZERO(&rfds);
+
+ /* Set time out values for select() */
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+
+ /* Add the sockets select() will examine */
+ for (i = 0; i < assoc_num; i++) {
+ FD_SET(client_socket[i], &rfds);
+ }
+
+ /* Wait until there is data to be read from one of the
+ * sockets, or until the timer expires
+ */
+ error = select(max_socket + 1, &rfds, NULL, NULL, &tv);
+
+ if (error < 0) {
+ printf("Select Failure: %s.\n", strerror(errno));
+ DUMP_CORE;
+ } else if (error) {
+ /* Loop through the array of sockets to find the ones
+ *that have information to be read
+ */
+ process_ready_sockets(client_socket, assoc_num, &rfds);
+ }
+ }
+}
+
+void process_ready_sockets(int client_socket[], int assoc_num, fd_set *rfds) {
+
+ int i, stream, error;
+ struct msghdr inmessage;
+ struct iovec iov;
+ char incmsg[CMSG_SPACE(sizeof (sctp_cmsg_data_t))];
+ sockaddr_storage_t msgname;
+
+ /* Setup inmessage to be able to receive in incomming message */
+ memset(&inmessage, 0, sizeof (inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen =1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof (incmsg);
+ inmessage.msg_name = &msgname;
+ inmessage.msg_namelen = sizeof (msgname);
+
+ stream = 1;
+
+ for( i = 0; i < assoc_num; i++) {
+ if (FD_ISSET(client_socket[i], rfds)) {
+ error = recvmsg(client_socket[i], &inmessage,
+ MSG_WAITALL);
+ if (error < 0)
+ printf("Receive Failure: %s\n",
+ strerror(errno));
+ else {
+ /* Test to find the type of message that was read(event/data) */
+ if (inmessage.msg_flags &
+ MSG_NOTIFICATION)
+ event_received(&inmessage,
+ 0);
+
+ else
+ data_received(&inmessage, error,
+ stream,
+ client_socket[i]);
+ }
+ }
+ }
+}
+
+int main(int argc, char *argv[]) {
+
+ parse_arguments(argc, argv);
+
+ if (mode == SERVER) {
+ server_mode();
+ } else if (mode == CLIENT){
+ client_mode();
+ }
+ exit(1);
+}
+
diff --git a/src/func_tests/.gitignore b/src/func_tests/.gitignore
new file mode 100644
index 0000000..720db65
--- /dev/null
+++ b/src/func_tests/.gitignore
@@ -0,0 +1,41 @@
+test_1_to_1_accept_close
+test_1_to_1_addrs
+test_1_to_1_connect
+test_1_to_1_connectx
+test_1_to_1_events
+test_1_to_1_initmsg_connect
+test_1_to_1_nonblock
+test_1_to_1_recvfrom
+test_1_to_1_recvmsg
+test_1_to_1_rtoinfo
+test_1_to_1_send
+test_1_to_1_sendmsg
+test_1_to_1_sendto
+test_1_to_1_shutdown
+test_1_to_1_socket_bind_listen
+test_1_to_1_sockopt
+test_1_to_1_threads
+test_assoc_abort
+test_assoc_shutdown
+test_autoclose
+test_basic
+test_basic_v6
+test_connect
+test_connectx
+test_fragments
+test_fragments_v6
+test_getname
+test_getname_v6
+test_inaddr_any
+test_inaddr_any_v6
+test_peeloff
+test_peeloff_v6
+test_recvmsg
+test_sctp_sendrecvmsg
+test_sctp_sendrecvmsg_v6
+test_sockopt
+test_sockopt_v6
+test_tcp_style
+test_tcp_style_v6
+test_timetolive
+test_timetolive_v6
diff --git a/src/func_tests/Makefile.am b/src/func_tests/Makefile.am
new file mode 100644
index 0000000..e5bf454
--- /dev/null
+++ b/src/func_tests/Makefile.am
@@ -0,0 +1,179 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I. -I$(top_builddir)/src/include -I$(top_srcdir)/src/testlib \
+ -g -O2 -fno-strict-aliasing -Wall -Wstrict-prototypes \
+ -Wimplicit-function-declaration
+
+AM_LDFLAGS = -lpthread
+
+LDADD = $(top_builddir)/src/testlib/libsctputil.la \
+ $(top_builddir)/src/lib/libsctp.la
+
+V6FLAGS = -DCONFIG_IPV6=1 -DTEST_V6=1 ${DEFS} ${INCLUDES} ${CFLAGS}
+
+# Test programs and libraries to build
+PASSING_KERN_TESTS = \
+ test_assoc_abort \
+ test_assoc_shutdown \
+ test_autoclose \
+ test_basic \
+ test_fragments \
+ test_inaddr_any \
+ test_peeloff \
+ test_sockopt \
+ test_connect \
+ test_connectx \
+ test_recvmsg \
+ test_timetolive \
+ test_sctp_sendrecvmsg \
+ test_getname \
+ test_tcp_style\
+ test_1_to_1_socket_bind_listen \
+ test_1_to_1_accept_close \
+ test_1_to_1_connect \
+ test_1_to_1_connectx \
+ test_1_to_1_send \
+ test_1_to_1_sendto \
+ test_1_to_1_sendmsg \
+ test_1_to_1_recvfrom \
+ test_1_to_1_recvmsg \
+ test_1_to_1_shutdown \
+ test_1_to_1_sockopt \
+ test_1_to_1_addrs \
+ test_1_to_1_nonblock \
+ test_1_to_1_rtoinfo \
+ test_1_to_1_events \
+ test_1_to_1_threads \
+ test_1_to_1_initmsg_connect
+
+PASSING_V6_KERN_TESTS = \
+ test_basic_v6 \
+ test_sockopt_v6 \
+ test_fragments_v6 \
+ test_inaddr_any_v6 \
+ test_peeloff_v6 \
+ test_timetolive_v6 \
+ test_sctp_sendrecvmsg_v6 \
+ test_getname_v6 \
+ test_tcp_style_v6
+
+if HAVE_SCTP_SENDV
+PASSING_KERN_TESTS += \
+ test_sctp_sendvrecvv
+PASSING_V6_KERN_TESTS += \
+ test_sctp_sendvrecvv_v6
+endif
+
+noinst_PROGRAMS = ${PASSING_KERN_TESTS} ${PASSING_V6_KERN_TESTS}
+
+$(top_builddir)/src/lib/libsctp.la:
+ $(MAKE) -C $(top_builddir)/src/lib libsctp.la
+
+$(top_builddir)/src/testlib/libsctputil.la:
+ $(MAKE) -C $(top_builddir)/src/testlib libsctputil.la
+
+# These are tests for live kernels which pass.
+v4test: ${PASSING_KERN_TESTS}
+ @for a in $^; \
+ do \
+ echo "./$$a"; \
+ if ./$$a; \
+ then \
+ echo "$$a passes"; \
+ echo ""; \
+ else \
+ echo "$$a fails"; \
+ exit 1; \
+ fi; \
+ sleep 1; \
+ done
+ @echo "Hoody hoo!"
+
+# These are tests for live kernels which pass.
+v6test: ${PASSING_V6_KERN_TESTS}
+ @for a in $^; \
+ do \
+ echo "./$$a"; \
+ if ./$$a; \
+ then \
+ echo "$$a passes"; \
+ echo ""; \
+ else \
+ echo "$$a fails"; \
+ exit 1; \
+ fi; \
+ sleep 1; \
+ done
+ @echo "Hoody hoo!"
+
+# Specifying the sources
+test_assoc_abort_SOURCES = test_assoc_abort.c
+test_assoc_shutdown_SOURCES = test_assoc_shutdown.c
+test_autoclose_SOURCES = test_autoclose.c
+test_basic_SOURCES = test_basic.c
+test_fragments_SOURCES = test_fragments.c
+test_inaddr_any_SOURCES = test_inaddr_any.c
+test_peeloff_SOURCES = test_peeloff.c
+test_sockopt_SOURCES = test_sockopt.c
+test_connect_SOURCES = test_connect.c
+test_connectx_SOURCES = test_connectx.c
+test_recvmsg_SOURCES = test_recvmsg.c
+test_timetolive_SOURCES = test_timetolive.c
+test_sctp_sendrecvmsg_SOURCES = test_sctp_sendrecvmsg.c
+test_sctp_sendvrecvv_SOURCES = test_sctp_sendvrecvv.c
+test_getname_SOURCES = test_getname.c
+test_tcp_style_SOURCES = test_tcp_style.c
+
+test_1_to_1_socket_bind_listen_SOURCES = test_1_to_1_socket_bind_listen.c
+test_1_to_1_accept_close_SOURCES = test_1_to_1_accept_close.c
+test_1_to_1_connect_SOURCES = test_1_to_1_connect.c
+test_1_to_1_connectx_SOURCES = test_1_to_1_connectx.c
+test_1_to_1_send_SOURCES = test_1_to_1_send.c
+test_1_to_1_sendto_SOURCES = test_1_to_1_sendto.c
+test_1_to_1_sendmsg_SOURCES = test_1_to_1_sendmsg.c
+test_1_to_1_recvfrom_SOURCES = test_1_to_1_recvfrom.c
+test_1_to_1_recvmsg_SOURCES = test_1_to_1_recvmsg.c
+test_1_to_1_shutdown_SOURCES = test_1_to_1_shutdown.c
+test_1_to_1_sockopt_SOURCES = test_1_to_1_sockopt.c
+test_1_to_1_addrs_SOURCES = test_1_to_1_addrs.c
+test_1_to_1_nonblock_SOURCES = test_1_to_1_nonblock.c
+test_1_to_1_rtoinfo_SOURCES = test_1_to_1_rtoinfo.c
+test_1_to_1_events_SOURCES = test_1_to_1_events.c
+test_1_to_1_threads_SOURCES = test_1_to_1_threads.c
+test_1_to_1_initmsg_connect_SOURCES = test_1_to_1_initmsg_connect.c
+
+#
+# Specifying objects rules for "v6test"
+#
+test_basic_v6_SOURCES = test_basic.c
+test_basic_v6_CFLAGS = ${V6FLAGS}
+
+test_sockopt_v6_SOURCES = test_sockopt.c
+test_sockopt_v6_CFLAGS = ${V6FLAGS}
+
+test_fragments_v6_SOURCES = test_fragments.c
+test_fragments_v6_CFLAGS = ${V6FLAGS}
+
+test_inaddr_any_v6_SOURCES = test_inaddr_any.c
+test_inaddr_any_v6_CFLAGS = ${V6FLAGS}
+
+test_peeloff_v6_SOURCES = test_peeloff.c
+test_peeloff_v6_CFLAGS = ${V6FLAGS}
+
+test_timetolive_v6_SOURCES = test_timetolive.c
+test_timetolive_v6_CFLAGS = ${V6FLAGS}
+
+test_sctp_sendrecvmsg_v6_SOURCES = test_sctp_sendrecvmsg.c
+test_sctp_sendvrecvv_v6_SOURCES = test_sctp_sendvrecvv.c
+test_sctp_sendrecvmsg_v6_CFLAGS = ${V6FLAGS}
+test_sctp_sendvrecvv_v6_CFLAGS = ${V6FLAGS}
+
+test_getname_v6_SOURCES = test_getname.c
+test_getname_v6_CFLAGS = ${V6FLAGS}
+
+test_tcp_style_v6_SOURCES = test_tcp_style.c
+test_tcp_style_v6_CFLAGS = ${V6FLAGS}
diff --git a/src/func_tests/test_1_to_1_accept_close.c b/src/func_tests/test_1_to_1_accept_close.c
new file mode 100644
index 0000000..64162f8
--- /dev/null
+++ b/src/func_tests/test_1_to_1_accept_close.c
@@ -0,0 +1,246 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the accept () and close () call for
+ * 1-1 style sockets
+ *
+ * accept () Tests:
+ * ---------------
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: On a non-listening socket
+ * TEST5: On a established socket
+ * TEST6: On a CLOSED association
+ * TEST7: Extracting the association on the listening socket
+ *
+ * close () Tests:
+ * --------------
+ * TEST8: Bad socket descriptor
+ * TEST9: valid socket descriptor
+ * TEST10: Closed socket descriptor
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX 10
+
+int
+main(int argc, char *argv[])
+{
+ socklen_t len;
+ int i;
+ int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk,pf_class;
+ int new_sk[SK_MAX],clnt2_sk[SK_MAX];
+ int error;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ for (i=0 ; i < SK_MAX ; i++)
+ new_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /* Creating a regular socket */
+ for (i = 0 ; i < SK_MAX ; i++)
+ clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ for (i = 0 ; i < SK_MAX ; i++)
+ clnt2_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /* Creating a listen socket */
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /* Binding the listen socket */
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /* Listening many sockets as we are calling too many connect here */
+ test_listen(lstn_sk, SK_MAX );
+
+ /* connect() is called just to make sure accept() doesn't block the
+ * program
+ */
+ i = 0;
+ len = sizeof(struct sockaddr_in);
+ test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+ /* accept() TEST1: Bad socket descriptor EBADF, Expected error */
+ error = accept(-1, (struct sockaddr *) &acpt_addr, &len);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "accept with a bad socket descriptor"
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept() with a bad socket descriptor - EBADF");
+
+ /*accept() TEST2: Invalid socket ENOTSOCK, Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = accept(fd, (struct sockaddr *) &acpt_addr, &len);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "accept with invalid socket"
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "accept() with invalid socket - ENOTSOCK");
+
+ /*accept() TEST3: Invalid address EFAULT, Expected error*/
+ error = accept(lstn_sk, (struct sockaddr *) -1, &len);
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "accept with invalid address"
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept() with invalid address - EFAULT");
+
+ test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+ /*accept() TEST4: on a non-listening socket EINVAL, Expected error*/
+ error = accept(sk, (struct sockaddr *) &acpt_addr, &len);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "accept on a non-listening socket"
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept() on a non-listening socket - EINVAL");
+
+ test_connect(clnt_sk[i++], (struct sockaddr *) &conn_addr, len);
+
+ /*Calling accept to establish the connection*/
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+
+ /* accept() TEST5: On a established socket EINVAL or EACCES when
+ * SELinux set to enforcing, Expected error. */
+ error = accept(acpt_sk, (struct sockaddr *) &acpt_addr, &len);
+ if (error != -1 || (errno != EINVAL && errno != EACCES)) {
+ tst_brkm(TBROK, tst_exit, "accept on an established socket"
+ "error:%d, errno:%d", error, errno);
+ }
+
+ tst_resm(TPASS, "accept() on an established socket - %d", errno);
+
+ /*Closing the previously established association*/
+ close(acpt_sk);
+
+ test_connect(clnt_sk[i], (struct sockaddr *) &conn_addr, len);
+
+ /*accept() TEST6: On the CLOSED association should succeed*/
+ acpt_sk = accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+ if (acpt_sk < 0)
+ tst_brkm(TBROK, tst_exit, "accept a closed association"
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept() a closed association - SUCCESS");
+
+ close(acpt_sk);
+
+ /*accept() TEST7: Extracting the association on the listening socket
+ as new socket, new socket socket descriptor should return*/
+ for (i = 0 ; i < (SK_MAX - 1); i++)
+ test_connect(clnt2_sk[i], (struct sockaddr *) &conn_addr, len);
+
+ for (i = 0 ; i < (SK_MAX - 1); i++)
+ new_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr,
+ &len);
+
+ tst_resm(TPASS, "accept() on a listening socket - SUCCESS");
+
+
+ /*close() TEST8: Bad socket descriptor, EBADF Expected error*/
+ error = close(-1);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "close with a bad socket descriptor "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "close() with a bad socket descriptor - EBADF");
+
+ /*close() TEST9: valid socket descriptor should succeed*/
+ error = close(sk);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "close with a valid socket descriptor"
+ " error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "close() with a valid socket descriptor - SUCCESS");
+
+ /*close() TEST10: closed socket descriptor, EBADF Expected error*/
+ error = close(sk);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "close with a closed socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "close() with a closed socket descriptor - EBADF");
+
+ for (i = 0 ; i < SK_MAX ; i++) {
+ close(clnt_sk[i]);
+ close(new_sk[i]);
+ close(clnt2_sk[i]);
+ }
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_addrs.c b/src/func_tests/test_1_to_1_addrs.c
new file mode 100644
index 0000000..5d56918
--- /dev/null
+++ b/src/func_tests/test_1_to_1_addrs.c
@@ -0,0 +1,289 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sctp_getladdrs (), sctp_freealddrs (),
+ * sctp_getpaddrs (), sctp_freeapaddrs () for 1-1 style sockets
+ *
+ * sctp_getladdrs () Tests:
+ * -----------------------
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Socket of different protocol
+ * TEST4: Getting the local addresses
+ *
+ * sctp_freealddrs () Tests:
+ * ------------------------
+ * TEST5: Freeing the local address
+ *
+ * sctp_getpaddrs () Tests:
+ * -----------------------
+ * TEST6: Bad socket descriptor
+ * TEST7: Invalid socket
+ * TEST8: Socket of different protocol
+ * TEST9: Getting the peers addresses
+ *
+ * sctp_freeapddrs () Tests:
+ * ------------------------
+ * TEST10: Freeing the peer's address
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int error;
+ socklen_t len;
+ int lstn_sk,clnt_sk,acpt_sk,pf_class,sk1;
+ struct msghdr outmessage;
+ struct msghdr inmessage;
+ char *message = "hello, world!\n";
+ struct iovec iov_rcv;
+ struct sctp_sndrcvinfo *sinfo;
+ int msg_count;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct iovec out_iov;
+ char * buffer_rcv;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ struct sockaddr *laddrs, *paddrs;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+ struct sockaddr_in *addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ /*Creating a regular socket*/
+ clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*Creating a listen socket*/
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening many sockets as we are calling too many connect here*/
+ test_listen(lstn_sk, 1);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ buffer_rcv = malloc(REALLY_BIG);
+
+ iov_rcv.iov_base = buffer_rcv;
+ iov_rcv.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov_rcv;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ msg_count = strlen(message) + 1;
+
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &lstn_addr;
+ outmessage.msg_namelen = sizeof(lstn_addr);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = msg_count;
+
+ test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count);
+
+ test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL);
+
+ /*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/
+ error = sctp_getladdrs(-1, 0, &laddrs);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs with a bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - "
+ "EBADF");
+
+ /*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = sctp_getladdrs(fd, 0, &laddrs);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs with invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK");
+
+ /*sctp_getladdrs() TEST3: socket of different protocol
+ EOPNOTSUPP Expected error*/
+ sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP);
+ error = sctp_getladdrs(sk1, 0, &laddrs);
+ if (error != -1 || errno != EOPNOTSUPP)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs with socket of "
+ "different protocol error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - "
+ "EOPNOTSUPP");
+
+ /*sctp_getladdrs() TEST4: Getting the local addresses*/
+ error = sctp_getladdrs(lstn_sk, 0, &laddrs);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs with valid socket "
+ "error:%d, errno:%d", error, errno);
+
+ addr = (struct sockaddr_in *)laddrs;
+ if (addr->sin_port != lstn_addr.sin_port ||
+ addr->sin_family != lstn_addr.sin_family ||
+ addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs comparision failed");
+
+ tst_resm(TPASS, "sctp_getladdrs() - SUCCESS");
+
+ /*sctp_freealddrs() TEST5: freeing the local address*/
+ if ((sctp_freeladdrs(laddrs)) < 0)
+ tst_brkm(TBROK, tst_exit, "sctp_freeladdrs "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS");
+
+ /*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/
+ error = sctp_getpaddrs(-1, 0, &paddrs);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with a bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - "
+ "EBADF");
+
+ /*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = sctp_getpaddrs(fd, 0, &paddrs);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK");
+
+ /*sctp_getpaddrs() TEST8: socket of different protocol
+ EOPNOTSUPP Expected error*/
+ error = sctp_getpaddrs(sk1, 0, &laddrs);
+ if (error != -1 || errno != EOPNOTSUPP)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with socket of "
+ "different protocol error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - "
+ "EOPNOTSUPP");
+
+ /*sctp_getpaddrs() TEST9: Getting the peer addresses*/
+ error = sctp_getpaddrs(acpt_sk, 0, &paddrs);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with valid socket "
+ "error:%d, errno:%d", error, errno);
+
+ addr = (struct sockaddr_in *)paddrs;
+ if (addr->sin_port != acpt_addr.sin_port ||
+ addr->sin_family != acpt_addr.sin_family ||
+ addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs comparision failed");
+
+ tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS");
+
+ /*sctp_freeapddrs() TEST10: freeing the peer address*/
+ if ((sctp_freepaddrs(paddrs)) < 0)
+ tst_brkm(TBROK, tst_exit, "sctp_freepaddrs "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS");
+
+ close(clnt_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_connect.c b/src/func_tests/test_1_to_1_connect.c
new file mode 100644
index 0000000..3ebc599
--- /dev/null
+++ b/src/func_tests/test_1_to_1_connect.c
@@ -0,0 +1,234 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the connect () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: Invalid address length
+ * TEST5: Invalid address family
+ * TEST6: Valid blocking connect
+ * TEST7: Connect when accept queue is full
+ * TEST8: On a listening socket
+ * TEST9: On established socket
+ * TEST10: Connect to re-establish a closed association.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include "sctputil.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX 10
+
+int
+main(int argc, char *argv[])
+{
+ int error,i;
+ socklen_t len;
+ int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class;
+ int sk1,clnt2_sk;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*Creating a listen socket*/
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*Creating a regular socket*/
+ for (i = 0 ; i < SK_MAX ; i++)
+ clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, SK_MAX-1);
+
+
+ /*connect () TEST1: Bad socket descriptor, EBADF Expected error*/
+ len = sizeof(struct sockaddr_in);
+ error = connect(-1, (const struct sockaddr *) &conn_addr, len);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "connect with bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() with bad socket descriptor - EBADF");
+
+ /*connect () TEST2: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = connect(fd, (const struct sockaddr *) &conn_addr, len);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "connect with invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "connect() with invalid socket - ENOTSOCK");
+
+ /*connect () TEST3: Invalid address, EFAULT Expected error*/
+ error = connect(sk, (const struct sockaddr *) -1, len);
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "connect with invalid address "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() with invalid address - EFAULT");
+
+ /*connect () TEST4: Invalid address length, EINVAL Expected error*/
+ error = connect(sk, (const struct sockaddr *) &conn_addr, (len - 3));
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "connect with invalid address length "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() with invalid address length - EINVAL");
+
+ /*connect () TEST5: Invalid address family, EINVAL Expect error*/
+ conn_addr.sin_family = 9090; /*Assigning invalid address family*/
+ error = connect(sk, (const struct sockaddr *) &conn_addr, len);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "connect with invalid address family "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() with invalid address family - EINVAL");
+
+ conn_addr.sin_family = AF_INET;
+
+ /*connect () TEST6: Blocking connect, should pass*/
+ /*All the be below blocking connect should pass as socket will be
+ listening SK_MAX clients*/
+ for (i = 0 ; i < SK_MAX ; i++) {
+ error = connect(clnt_sk[i], (const struct sockaddr *)&conn_addr,
+ len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "valid blocking connect "
+ "error:%d, errno:%d", error, errno);
+ }
+
+ tst_resm(TPASS, "valid blocking connect() - SUCCESS");
+
+ /*connect () TEST7: connect when accept queue is full, ECONNREFUSED
+ Expect error*/
+ /*Now that accept queue is full, the below connect should fail*/
+ error = connect(clnt2_sk, (const struct sockaddr *) &conn_addr, len);
+ if (error != -1 || errno != ECONNREFUSED)
+ tst_brkm(TBROK, tst_exit, "connect when accept queue is full "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() when accept queue is full - ECONNREFUSED");
+
+ /*Calling a accept first to estblish the pending connections*/
+ for (i=0 ; i < SK_MAX ; i++)
+ acpt_sk[i] = test_accept(lstn_sk,
+ (struct sockaddr *) &acpt_addr, &len);
+
+ /*connect () TEST8: from a listening socket, EISCONN Expect error*/
+ error = connect(lstn_sk, (const struct sockaddr *) &lstn_addr, len);
+ if (error != -1 || errno != EISCONN)
+ tst_brkm(TBROK, tst_exit, "connect on a listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() on a listening socket - EISCONN");
+
+ /*connect() TEST9: On established socket, EISCONN Expect error*/
+ i=0;
+ error = connect(acpt_sk[i], (const struct sockaddr *) &lstn_addr, len);
+ if (error != -1 || errno != EISCONN)
+ tst_brkm(TBROK, tst_exit, "connect on an established socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() on an established socket - EISCONN");
+
+ for (i = 0 ; i < 4 ; i++) {
+ close(clnt_sk[i]);
+ close(acpt_sk[i]);
+ }
+
+ /* connect() TEST10: Re-establish an association that is closed.
+ * should succeed.
+ */
+ error = connect(sk1, (const struct sockaddr *)&conn_addr, len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "Re-establish an association that "
+ "is closed error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect() to re-establish a closed association - "
+ "SUCCESS");
+
+ close(sk);
+ close(sk1);
+ close(lstn_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_connectx.c b/src/func_tests/test_1_to_1_connectx.c
new file mode 100644
index 0000000..3cb18b3
--- /dev/null
+++ b/src/func_tests/test_1_to_1_connectx.c
@@ -0,0 +1,226 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sctp_connectx () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid address
+ * TEST4: Invalid address length
+ * TEST5: Invalid address family
+ * TEST6: Valid blocking sctp_connectx
+ * TEST7: Connect when accept queue is full
+ * TEST8: On a listening socket
+ * TEST9: On established socket
+ * TEST10: Connect to re-establish a closed association.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include "sctputil.h"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+#define SK_MAX 10
+
+int
+main(int argc, char *argv[])
+{
+ int error,i;
+ socklen_t len;
+ int sk,lstn_sk,clnt_sk[SK_MAX],acpt_sk[SK_MAX],pf_class;
+ int sk1,clnt2_sk;
+
+ struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
+ struct sockaddr *tmp_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*Creating a listen socket*/
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*Creating a regular socket*/
+ for (i = 0 ; i < SK_MAX ; i++)
+ clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ clnt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, SK_MAX-1);
+
+
+ /*sctp_connectx () TEST1: Bad socket descriptor, EBADF Expected error*/
+ len = sizeof(struct sockaddr_in);
+ error = sctp_connectx(-1, (struct sockaddr *) &conn_addr, 1, NULL);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx with bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() with bad socket descriptor - EBADF");
+
+ /*sctp_connectx () TEST2: Invalid socket, ENOTSOCK Expected error*/
+ error = sctp_connectx(0, (struct sockaddr *) &conn_addr, 1, NULL);
+ if (error != -1 || errno != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() with invalid socket - ENOTSOCK");
+
+ /*sctp_connectx () TEST3: Invalid address, EINVAL Expected error*/
+ tmp_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr) - 1);
+ tmp_addr->sa_family = AF_INET;
+ error = sctp_connectx(sk, tmp_addr, 1, NULL);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() with invalid address - EINVAL");
+
+ /*sctp_connectx () TEST4: Invalid address length, EINVAL Expected error*/
+ error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 0, NULL);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address length "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() with invalid address length - EINVAL");
+
+ /*sctp_connectx () TEST5: Invalid address family, EINVAL Expect error*/
+ conn_addr.sin_family = 9090; /*Assigning invalid address family*/
+ error = sctp_connectx(sk, (struct sockaddr *) &conn_addr, 1, NULL);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx with invalid address family "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() with invalid address family - EINVAL");
+
+ conn_addr.sin_family = AF_INET;
+
+ /*sctp_connectx () TEST6: Blocking sctp_connectx, should pass*/
+ /*All the be below blocking sctp_connectx should pass as socket will be
+ listening SK_MAX clients*/
+ for (i = 0 ; i < SK_MAX ; i++) {
+ error = sctp_connectx(clnt_sk[i], (struct sockaddr *)&conn_addr,
+ 1, NULL);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "valid blocking sctp_connectx "
+ "error:%d, errno:%d", error, errno);
+ }
+
+ tst_resm(TPASS, "valid blocking sctp_connectx() - SUCCESS");
+
+ /*sctp_connectx () TEST7: sctp_connectx when accept queue is full, ECONNREFUSED
+ Expect error*/
+ /*Now that accept queue is full, the below sctp_connectx should fail*/
+ error = sctp_connectx(clnt2_sk, (struct sockaddr *) &conn_addr, 1, NULL);
+ if (error != -1 || errno != ECONNREFUSED)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx when accept queue is full "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() when accept queue is full - ECONNREFUSED");
+
+ /*Calling a accept first to estblish the pending sctp_connectxions*/
+ for (i=0 ; i < SK_MAX ; i++)
+ acpt_sk[i] = test_accept(lstn_sk,
+ (struct sockaddr *) &acpt_addr, &len);
+
+ /*sctp_connectx () TEST8: from a listening socket, EISCONN Expect error*/
+ error = sctp_connectx(lstn_sk, (struct sockaddr *) &lstn_addr, 1, NULL);
+ if (error != -1 || errno != EISCONN)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx on a listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() on a listening socket - EISCONN");
+
+ /*sctp_connectx() TEST9: On established socket, EISCONN Expect error*/
+ i=0;
+ error = sctp_connectx(acpt_sk[i], (struct sockaddr *) &lstn_addr, 1, NULL);
+ if (error != -1 || errno != EISCONN)
+ tst_brkm(TBROK, tst_exit, "sctp_connectx on an established socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() on an established socket - EISCONN");
+
+ for (i = 0 ; i < 4 ; i++) {
+ close(clnt_sk[i]);
+ close(acpt_sk[i]);
+ }
+
+ /* sctp_connectx() TEST10: Re-establish an association that is closed.
+ * should succeed.
+ */
+ error = sctp_connectx(sk1, (struct sockaddr *)&conn_addr, 1, NULL);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "Re-establish an association that "
+ "is closed error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sctp_connectx() to re-establish a closed association - "
+ "SUCCESS");
+
+ close(sk);
+ close(sk1);
+ close(lstn_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_events.c b/src/func_tests/test_1_to_1_events.c
new file mode 100644
index 0000000..f758d6f
--- /dev/null
+++ b/src/func_tests/test_1_to_1_events.c
@@ -0,0 +1,205 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This test tests the events for 1-1 style sockets.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h> /* needed by linux/sctp.h */
+#include <sys/uio.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+#include <string.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk,acpt_sk;
+ struct sockaddr_in svr_loop, clt_loop,acpt_loop;
+ struct iovec iov, out_iov;
+ struct msghdr inmessage, outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ int error;
+ socklen_t len;
+ char *big_buffer;
+ struct sctp_event_subscribe event;
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ char *message = "hello, world!\n";
+ uint32_t ppid;
+ uint32_t stream;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+ svr_loop.sin_family = AF_INET;
+ svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.sin_port = htons(SCTP_TESTPORT_1);
+
+ clt_loop.sin_family = AF_INET;
+ clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop.sin_port = htons(SCTP_TESTPORT_1);
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(svr_sk, (struct sockaddr *) &svr_loop, sizeof(svr_loop));
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 3);
+
+ /* Create the client socket. */
+ clt_sk = test_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ memset(&event, 0, sizeof(event));
+ event.sctp_data_io_event = 1;
+ event.sctp_association_event = 1;
+ event.sctp_shutdown_event = 1;
+#ifdef HAVE_SCTP_AUTH_NO_AUTH
+ event.sctp_authentication_event = 1;
+#endif
+ len = sizeof(struct sctp_event_subscribe);
+ test_setsockopt(svr_sk, SCTP_EVENTS, &event, len);
+ test_setsockopt(clt_sk, SCTP_EVENTS, &event, len);
+
+ len = sizeof(struct sockaddr_in);
+ test_connect(clt_sk, (struct sockaddr *) &clt_loop, len);
+
+ acpt_sk = test_accept(svr_sk, (struct sockaddr *) &acpt_loop, &len);
+
+ /* Build up a msghdr structure we can use for all sending. */
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = (strlen(message) + 1);
+
+ /* Send . This will create the association*/
+ test_sendmsg(clt_sk, &outmessage, 0, strlen(message)+1);
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ /* NOW initialize inmessage with enough space for DATA... */
+ big_buffer = malloc(REALLY_BIG);
+ if (!big_buffer) { DUMP_CORE; }
+
+ /* Let's do a test to do a recvmsg when we are not listening and
+ * when we have no associations.
+ */
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ error = test_recvmsg(clt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage,
+ error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE,
+ SCTP_COMM_UP);
+
+ tst_resm(TPASS, "COMM_UP notification on client socket - SUCCESS");
+
+ error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage,
+ error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE,
+ SCTP_COMM_UP);
+
+ tst_resm(TPASS, "COMM_UP notification on server socket - SUCCESS");
+
+#ifdef HAVE_SCTP_AUTH_NO_AUTH
+ error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage,
+ error,
+ sizeof(struct sctp_authkey_event),
+ SCTP_AUTHENTICATION_EVENT,
+ SCTP_AUTH_NO_AUTH);
+
+ tst_resm(TPASS, "AUTH_NO_AUTH notification on server socket - SUCCESS");
+#endif
+
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+
+ tst_resm(TPASS, "Data message on server socket - SUCCESS");
+
+ close(clt_sk);
+ error = test_recvmsg(acpt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage,
+ error,
+ sizeof(struct sctp_shutdown_event),
+ SCTP_SHUTDOWN_EVENT,
+ 0);
+
+ tst_resm(TPASS, "SHUTDOWN notification on accepted socket - SUCCESS");
+ close(svr_sk);
+ close(acpt_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_initmsg_connect.c b/src/func_tests/test_1_to_1_initmsg_connect.c
new file mode 100644
index 0000000..8efb4f5
--- /dev/null
+++ b/src/func_tests/test_1_to_1_initmsg_connect.c
@@ -0,0 +1,120 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * When init timeout is set to zero, a connect () crashed the system. This case
+ * tests the fix for the same.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int
+main (int argc, char **argv)
+{
+ int sk1, sk2, sk3, pf_class;
+ socklen_t len;
+ struct sockaddr_in lstn_addr, acpt_addr;
+ struct sockaddr_in conn_addr;
+ char * buffer_rcv;
+ struct sctp_initmsg sinmsg;
+ char *message = "Hello World!\n";
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ /* Opening the socket*/
+
+ pf_class = PF_INET;
+
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ sk3 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ test_bind(sk3, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ len = sizeof(struct sctp_initmsg);
+ sinmsg.sinit_num_ostreams = 65535;
+ sinmsg.sinit_max_instreams = 10;
+ sinmsg.sinit_max_attempts = 1;
+ sinmsg.sinit_max_init_timeo = 0;
+ test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, len);
+ sinmsg.sinit_num_ostreams = 10;
+ sinmsg.sinit_max_instreams = 65535;
+ test_setsockopt(sk3, SCTP_INITMSG, &sinmsg, len);
+
+ test_listen(sk3, 1);
+
+ len = sizeof(struct sockaddr_in);
+ test_connect(sk1, (struct sockaddr *) &conn_addr, len);
+
+ sk2 = test_accept(sk3, (struct sockaddr *) &acpt_addr, &len);
+
+ test_sctp_sendmsg(sk1, message, strlen(message) + 1,
+ (struct sockaddr *)&conn_addr, len,
+ 0, 0, 65534, 0, 0);
+
+ buffer_rcv = malloc(100);
+ test_recv(sk2, buffer_rcv, (strlen(message) + 1), MSG_NOSIGNAL);
+
+ tst_resm(TPASS, "connect() with init timeout set to 0 - SUCCESS");
+
+ close (sk1);
+ close (sk2);
+ close (sk3);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_nonblock.c b/src/func_tests/test_1_to_1_nonblock.c
new file mode 100644
index 0000000..1179fb1
--- /dev/null
+++ b/src/func_tests/test_1_to_1_nonblock.c
@@ -0,0 +1,209 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the Non-Blocking mode of connect(),
+ * accept() and recvmsg() calls.
+ *
+ * TEST1: Non blocking accept return EAGAIN if connect is not called
+ * TEST2: Non blocking connect should return EINPROGRESS
+ * TEST3: accept() passes when connect called in Non-blocking mode
+ * TEST4: Non blocking recvmsg should return EAGAIN
+ * TEST5: recvmsg() should succeed if data present to receive in non blocking
+ * mode
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 5;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int error,msg_count;
+ socklen_t len;
+ int sk,pf_class,lstn_sk,acpt_sk,flag,cflag,sflag;
+ struct msghdr outmessage;
+ struct msghdr inmessage;
+ char *message = "hello, world!\n";
+ struct iovec iov_rcv;
+ struct sctp_sndrcvinfo *sinfo;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct iovec out_iov;
+ char * buffer_rcv;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbufferd
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+ flag = MSG_NOSIGNAL;
+
+ /*Setting server socket non-blocking*/
+ sflag = fcntl(lstn_sk, F_GETFL, 0);
+ if (sflag < 0)
+ tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed "
+ "sflag:%d, errno:%d", sflag, errno);
+
+ error = fcntl(lstn_sk, F_SETFL, sflag | O_NONBLOCK);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed "
+ "error:%d, errno:%d", error, errno);
+
+ /* TEST1: accept should return EAGAIN instead blocking. */
+ error = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+ if (error != -1 || errno != EAGAIN)
+ tst_brkm(TBROK, tst_exit, "non-blocking accept "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "non-blocking accept() - EAGAIN");
+
+ /* TEST2: Non Block connect should return EINPROGRESS */
+ /*Set client socket as non-blocking*/
+ cflag = fcntl(sk, F_GETFL, 0);
+ if (cflag < 0)
+ tst_brkm(TBROK, tst_exit, "fcnt F_GETFL failed "
+ "cflag:%d, errno:%d", cflag, errno);
+
+ error = fcntl(sk, F_SETFL, sflag | O_NONBLOCK);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "fcnt F_SETFL failed "
+ "error:%d, errno:%d", error, errno);
+
+ error = connect(sk, (const struct sockaddr *) &conn_addr, len);
+ if (error != -1 || errno != EINPROGRESS)
+ tst_brkm(TBROK, tst_exit, "non-blocking connect "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "non-blocking connect() - EINPROGRESS");
+
+ /* TEST3: Now that connect() called, accept will succeed */
+ acpt_sk = accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+ if (acpt_sk < 0)
+ tst_brkm(TBROK, tst_exit, "accept after a non-blocking connect "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept() after a non-blocking connect - SUCCESS");
+
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &svr_addr;
+ outmessage.msg_namelen = sizeof(svr_addr);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ buffer_rcv = malloc(REALLY_BIG);
+
+ iov_rcv.iov_base = buffer_rcv;
+ iov_rcv.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov_rcv;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ msg_count = strlen(message) + 1;
+
+ /* TEST4: recvmsg() should return EAGAIN instead blocking */
+ error = recvmsg(sk, &inmessage, MSG_WAITALL);
+ if ( error != -1 || errno != EAGAIN)
+ tst_brkm(TBROK, tst_exit, "non-blocking recvmsg "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "non-blocking recvmsg() - EAGAIN");
+
+ test_sendmsg(acpt_sk, &outmessage, flag, msg_count);
+
+ /* TEST5: recvmsg() should succeed now as data is available. */
+ error = test_recvmsg(sk, &inmessage, flag);
+ test_check_msg_data(&inmessage, error, msg_count, MSG_EOR, 0, 0);
+
+ tst_resm(TPASS, "non-blocking recvmsg() when data is available - "
+ "SUCCESS");
+
+ close(lstn_sk);
+ close(acpt_sk);
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_recvfrom.c b/src/func_tests/test_1_to_1_recvfrom.c
new file mode 100644
index 0000000..0ede562
--- /dev/null
+++ b/src/func_tests/test_1_to_1_recvfrom.c
@@ -0,0 +1,205 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the recvfrom () call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid message pointer
+ * TEST4: On a listening socket
+ * TEST5: Reading on a socket that received SHUTDOWN
+ * TEST6: Reading the pending message on socket that received SHUTDOWN
+ * TEST7: No more message and association is shutdown
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 7;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int msg_count;
+ socklen_t len;
+ int sk,pf_class,lstn_sk,acpt_sk, flag;
+ char *message = "hello, world!\n";
+ char *message_rcv;
+ int count;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ message_rcv = malloc(512);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ msg_count = (strlen(message) + 1);
+
+ flag = MSG_NOSIGNAL;
+ /*Sending the message*/
+ count = test_send(sk, message, msg_count, flag);
+
+ /*recvfrom () TEST1: Bad socket descriptor, EBADF Expected error*/
+ count = recvfrom(-1, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "recvfrom with a bad socket "
+ "descriptor count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvfrom() with a bad socket descriptor - EBADF");
+
+ /*recvfrom () TEST2: Invalid socket , ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ count = recvfrom(fd, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (count != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "recvfrom with invalid socket "
+ "count:%d, errno:%d", count, err_no);
+
+ tst_resm(TPASS, "recvfrom() with invalid socket - ENOTSOCK");
+
+ /*recvfrom () TEST3: Invalid message pointer EFAULT, Expected error*/
+ count = recvfrom(acpt_sk, (char *)-1, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "recvfrom with invalid message "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvfrom() with invalid message ptr - EFAULT");
+
+ /*TEST4: recvfrom on listening socket,ENOTCONN Expected error*/
+ count = recvfrom(lstn_sk, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count != -1 || errno != ENOTCONN)
+ tst_brkm(TBROK, tst_exit, "recvfrom on listening socket "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvfrom() on listening socket - ENOTCONN");
+
+ count = test_send(acpt_sk, message, msg_count, flag);
+
+ test_shutdown(sk, SHUT_WR);
+
+ /*recvfrom () TEST5:reading on a socket that received SHUTDOWN*/
+ count = recvfrom(acpt_sk, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count < 0)
+ tst_brkm(TBROK, tst_exit, "recvfrom on a socket that has "
+ "received shutdown count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvfrom() on a socket that has received shutdown - "
+ "EOF");
+
+ /*recvfrom () TEST6:reading the pending message on socket that sent
+ SHUTDOWN*/
+ count = recvfrom(sk, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count < 0)
+ tst_brkm(TBROK, tst_exit, "recvfrom on a socket with pending "
+ "message that has sent shutdown count:%d, errno:%d",
+ count, errno);
+
+ tst_resm(TPASS, "recvfrom() on a socket with pending message that has "
+ "sent shutdown - SUCCESS");
+
+ /*recvfrom () TEST7: No more message and association is shutdown,
+ ENOTCONN Expected error*/
+ count = recvfrom(sk, message_rcv, msg_count, flag,
+ (struct sockaddr *)&svr_addr, &len);
+ if (count != -1 || errno != ENOTCONN)
+ tst_brkm(TBROK, tst_exit, "recvfrom on a socket with no "
+ "pending messages and has sent shutdown count:%d, "
+ "errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvfrom() on a socket with no pending messages and "
+ " has sent shutdown - ENOTCONN");
+
+ close(sk);
+ close(lstn_sk);
+ close(acpt_sk);
+ return 0;
+
+}
diff --git a/src/func_tests/test_1_to_1_recvmsg.c b/src/func_tests/test_1_to_1_recvmsg.c
new file mode 100644
index 0000000..5f06bb6
--- /dev/null
+++ b/src/func_tests/test_1_to_1_recvmsg.c
@@ -0,0 +1,216 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the recvmsg() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: Invalid iovec pointer
+ * TEST4: Invalid msghdr pointer
+ * TEST5: On a listening socket
+ * TEST6: Reading on a socket that received SHUTDOWN
+ * TEST7: Reading the pending message socket that received SHUTDOWN
+ * TEST8: No more message and association is shutdown
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 8;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ socklen_t len;
+ int sk,pf_class,lstn_sk,acpt_sk;
+ int flag = 0;
+ int fd, err_no = 0;
+ char filename[21];
+ struct msghdr inmessage;
+ char *message = "hello, world!\n";
+ struct iovec iov_rcv;
+ int count;
+ char * buffer_rcv;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char *message1 = "hello, world!\n";
+
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ buffer_rcv = malloc(REALLY_BIG);
+
+ iov_rcv.iov_base = buffer_rcv;
+ iov_rcv.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov_rcv;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /*recvmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
+ count = recvmsg(-1, &inmessage, flag);
+ if (count != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "recvmsg with a bad socket "
+ "descriptor count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() with a bad socket descriptor - EBADF");
+
+ /*recvmsg () TEST2: Invalid socket , ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ count = recvmsg(fd, &inmessage, flag);
+ if (count == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (count != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "recvmsg with invalid socket "
+ "count:%d, errno:%d", count, err_no);
+
+ tst_resm(TPASS, "recvmsg() with invalid socket - ENOTSOCK");
+
+ /*recvmsg () TEST3: Invalid iovec pointer EFAULT, Expected error*/
+ inmessage.msg_iov = (struct iovec *)-1;
+ count = recvmsg(acpt_sk, &inmessage, flag);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "recvmsg with invalid iovec "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() with invalid iovec ptr - EFAULT");
+
+ inmessage.msg_iov = &iov_rcv;
+
+ /*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/
+ count = recvmsg(acpt_sk, (struct msghdr *)-1, flag);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() with invalid msghdr ptr - EFAULT");
+
+ /*recvmsg () TEST5:recvmsg on listening socket,ENOTCONN Expected error*/
+ count = recvmsg(lstn_sk, &inmessage, flag);
+ if (count != -1 || errno != ENOTCONN)
+ tst_brkm(TBROK, tst_exit, "recvmsg on listening socket "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() on listening socket - ENOTCONN");
+
+ count = test_send(acpt_sk, message1, strlen(message), 0);
+
+ test_shutdown(sk, SHUT_WR);
+
+ flag = MSG_NOSIGNAL;
+ /*recvmsg () TEST6:reading on a socket that received SHUTDOWN*/
+ count = recvmsg(acpt_sk, &inmessage, flag);
+ if (count < 0)
+ tst_brkm(TBROK, tst_exit, "recvmsg on a socket that has "
+ "received shutdown count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() on a socket that has received shutdown - "
+ "EOF");
+
+ /*recvmsg () TEST7:reading the pending message socket that sent
+ SHUTDOWN*/
+ count = recvmsg(sk, &inmessage, flag);
+ if (count < 0)
+ tst_brkm(TBROK, tst_exit, "recvmsg on a socket with pending "
+ "message that has sent shutdown count:%d, errno:%d",
+ count, errno);
+
+ tst_resm(TPASS, "recvmsg() on a socket with pending message that has "
+ "sent shutdown - SUCCESS");
+
+ /*recvmsg () TEST8: No more message and association is shutdown,
+ ENOTCONN Expected error*/
+ count = recvmsg(sk, &inmessage, flag);
+ if (count != -1 || errno != ENOTCONN)
+ tst_brkm(TBROK, tst_exit, "recvmsg on a socket with no "
+ "pending messages and has sent shutdown count:%d, "
+ "errno:%d", count, errno);
+
+ tst_resm(TPASS, "recvmsg() on a socket with no pending messages and "
+ " has sent shutdown - ENOTCONN");
+
+ close(sk);
+ close(lstn_sk);
+ close(acpt_sk);
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_rtoinfo.c b/src/func_tests/test_1_to_1_rtoinfo.c
new file mode 100644
index 0000000..1651df1
--- /dev/null
+++ b/src/func_tests/test_1_to_1_rtoinfo.c
@@ -0,0 +1,115 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the getsockopt () and sectsockopt () with
+ * SCTP_RTOINFO option on 1-1 style socket
+ *
+ * This program first gets the default values using getsockopt(). It also sets
+ * the value using setsockopt() and gets the set value using getsockopt().
+ * A comparison between set values and get values are performed.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+#include <linux/in.h> /* for sockaddr_in */
+#include <linux/in6.h> /* for sockaddr_in6 */
+#include <errno.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 3;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+
+ int sd, ret;
+ socklen_t len;
+ struct sctp_rtoinfo srtoinfo; /*setting the variables*/
+ struct sctp_rtoinfo grtoinfo; /*Getting the variables*/
+
+ sd = test_socket (PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ len = sizeof(struct sctp_rtoinfo);
+
+ /*TEST1 Getting the default values using getsockopt()*/
+ ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len);
+ if (ret < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO "
+ "ret:%d, errno:%d", ret, errno);
+
+ tst_resm(TPASS, "getsockopt() SCTP_RTOINFO - SUCCESS");
+
+ /*Assigning the values to RTO initial and max and min bounds*/
+ srtoinfo.srto_initial=60;
+ srtoinfo.srto_max=100;
+ srtoinfo.srto_min=40;
+ srtoinfo.srto_assoc_id = 0;
+
+ /*TEST2 Setting the values using setsockopt()*/
+ ret = setsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &srtoinfo,
+ sizeof(struct sctp_rtoinfo));
+ if (ret < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SCTP_RTOINFO "
+ "ret:%d, errno:%d", ret, errno);
+
+ tst_resm(TPASS, "setsockopt() SCTP_RTOINFO - SUCCESS");
+
+ /*Getting the values which are set using setsockopt()*/
+ ret = getsockopt(sd, IPPROTO_SCTP, SCTP_RTOINFO, &grtoinfo, &len);
+ if (ret < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_RTOINFO "
+ "ret:%d, errno:%d", ret, errno);
+
+ /* TEST3 Compare the get values with the set values. */
+ if (srtoinfo.srto_initial != grtoinfo.srto_initial &&
+ srtoinfo.srto_max != grtoinfo.srto_max &&
+ srtoinfo.srto_min != grtoinfo.srto_min)
+ tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_RTOINFO "
+ "compare failed");
+
+ tst_resm(TPASS, "setsockopt()/getsockopt SCTP_RTOINFO compare - "
+ "SUCCESS");
+
+ close(sd);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_send.c b/src/func_tests/test_1_to_1_send.c
new file mode 100644
index 0000000..8d9516c
--- /dev/null
+++ b/src/func_tests/test_1_to_1_send.c
@@ -0,0 +1,241 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the send() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: On a listening socket
+ * TEST4: On a closed association
+ * TEST5: Invalid message address
+ * TEST6: send from client to server
+ * TEST7: send from server to client
+ * TEST8: sending partial data from a buffer
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 8;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ socklen_t len,len_snd;
+ int msg_count;
+ int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag, count;
+ char *message = "hello, world!\n";
+ char *message_rcv;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ len_snd = (strlen(message) + 1);
+
+ flag = MSG_NOSIGNAL;
+ /*send () TEST1: Bad socket descriptor, EBADF Expected error*/
+ count = send(-1, message, len_snd, flag);
+ if (count != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "send with a bad socket "
+ "descriptor count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() with a bad socket descriptor - EBADF");
+
+ /*send () TEST2: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ count = send(fd, message, len_snd, flag);
+ if (count == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (count != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "send with invalid socket "
+ "count:%d, errno:%d", count, err_no);
+
+ tst_resm(TPASS, "send() with invalid socket - ENOTSOCK");
+
+ /*send () TEST3: send on listening socket, EPIPE Expected error*/
+ count = send(lstn_sk, message, len_snd, flag);
+ if (count != -1 || errno != EPIPE)
+ tst_brkm(TBROK, tst_exit, "send on a listening socket "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() on a listening socket - EPIPE");
+#if 0
+ /*send () TEST4: Invalid message address, EFAULT Expected error*/
+ /* FIXME this test should pass. Don't catch why... */
+ count = send(sk, (char *)0x1, len_snd, flag);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "send with invalid message "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() with invalid message ptr - EFAULT");
+#endif
+
+ test_connect(sk1, (struct sockaddr *) &lstn_addr, len);
+
+ count = test_send(sk1, message, len_snd, flag);
+
+ close(sk1);
+
+ acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len);
+
+ /*send () TEST5: send on closed association, EPIPE Expected error*/
+ count = send(acpt1_sk, message, len_snd, flag);
+ if (count != -1 || errno != EPIPE)
+ tst_brkm(TBROK, tst_exit, "send on a closed association "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() on a closed association - EPIPE");
+
+ close(acpt1_sk);
+ close(sk);
+ close(lstn_sk);
+ close(acpt_sk);
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ message_rcv = malloc(512);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ msg_count = strlen(message) + 1;
+
+ /*send() TEST6: Sending data from client socket to server socket*/
+ count = send(sk, message, msg_count, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "send from client to server "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() from client to server - SUCCESS");
+
+ test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+ strncpy(message_rcv,"\0",512);
+
+ /*send() TEST7: Sending data from accept socket to client socket*/
+ count = send(acpt_sk, message, msg_count, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "send from accept socket to client "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "send() from accept socket to client - SUCCESS");
+
+ test_recv(sk, message_rcv, msg_count, flag);
+
+ /*send() TEST8: Sending less number of data from the buffer*/
+ /*Sending only 5 bytes so that only hello is received*/
+ test_send(sk, message, 5 , flag);
+ test_recv(acpt_sk, message_rcv, 5, flag);
+
+ tst_resm(TPASS, "send() partial data from a buffer - SUCCESS");
+
+ /* TEST9: sctp_send with no sinfo */
+ test_sctp_send(sk, message, strlen(message) + 1 , NULL, flag);
+ test_recv(acpt_sk, message_rcv, strlen(message) + 1, flag);
+ tst_resm(TPASS, "sctp_send() with no sinfo - SUCCESS");
+
+ close(sk1);
+ close(lstn_sk);
+ close(acpt_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sendmsg.c b/src/func_tests/test_1_to_1_sendmsg.c
new file mode 100644
index 0000000..13c920d
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sendmsg.c
@@ -0,0 +1,377 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sendmsg() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: On a listening socket
+ * TEST4: Invalid iovec pointer
+ * TEST5: Invalid iovec length
+ * TEST6: Invalid msghdr pointer
+ * TEST7: Invalid sinfo flags
+ * TEST8: SCTP_EOF flag set
+ * TEST9: SCTP_ABORT flag set
+ * TEST10: On a closed association
+ *
+ * TEST11: Sending data from server socket to client socket
+ * TEST12: Sending data from client socket to server socket
+ * TEST13: Sending data from unconnected client to server
+ * TEST14: Sending a message on SHUT_RD socket
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 14;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ socklen_t len;
+ int msg_count;
+ int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag;
+ struct msghdr outmessage;
+ char *message = "hello, world!\n";
+ struct sctp_sndrcvinfo *sinfo;
+ int count;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct iovec out_iov;
+ struct msghdr inmessage;
+ char * buffer_rcv;
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+ struct iovec iov_rcv;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ int fd, err_no = 0;
+ char filename[21];
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &conn_addr;
+ outmessage.msg_namelen = sizeof(conn_addr);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+ flag = MSG_NOSIGNAL;
+ /*sendmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
+ count = sendmsg(-1, &outmessage, flag);
+ if (count != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "sendmsg with a bad socket "
+ "descriptor count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with a bad socket descriptor - EBADF");
+
+ /*sendmsg () TEST2: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ count = sendmsg(fd, &outmessage, flag);
+ if (count == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (count != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "sendmsg with invalid socket "
+ "count:%d, errno:%d", count, err_no);
+
+ tst_resm(TPASS, "sendmsg() with invalid socket - ENOTSOCK");
+
+ /*sendmsg () TEST3: sendmsg on listening socket, EPIPE Expected error*/
+ count = sendmsg(lstn_sk, &outmessage, flag);
+ if (count != -1 || errno != EPIPE)
+ tst_brkm(TBROK, tst_exit, "sendmsg on a listening socket "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() on a listening socket - EPIPE");
+
+ /*sendmsg () TEST4: Invalid iovec pointer EFAULT, Expected error*/
+ outmessage.msg_iov = (struct iovec *)-1;
+ count = sendmsg(sk, &outmessage, flag);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with invalid iovec ptr - EFAULT");
+
+ outmessage.msg_iov = &out_iov;
+
+ /*sendmsg () TEST5: Invalid iovec count EINVAL, Expected error*/
+ outmessage.msg_iovlen = 0;
+ count = sendmsg(sk, &outmessage, flag);
+ if (count != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec "
+ "length count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with invalid iovec length - EINVAL");
+
+ outmessage.msg_iovlen = 1;
+
+ /*sendmsg () TEST6: Invalid msghdr pointer EFAULT, Expected error*/
+ count = sendmsg(sk, (struct msghdr *)-1, flag);
+ if (count != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "sendmsg with invalid msghdr "
+ "pointer count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with invalid msghdr ptr - EFAULT");
+
+ /*sendmsg () TEST7: Invalid sinfo flag EINVAL, Expected error*/
+ sinfo->sinfo_flags = 999;
+ count = sendmsg(sk, &outmessage, -1);
+ if (count != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sendmsg with invalid sinfo "
+ "flags count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with invalid sinfo flags - EINVAL");
+
+ /*sendmsg () TEST8: SCTP_EOF flag EINVAL, Expected error*/
+ sinfo->sinfo_flags = SCTP_EOF;
+ count = sendmsg(sk, &outmessage, flag);
+ if (count != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with SCTP_EOF flag - EINVAL");
+
+ /*sendmsg () TEST9: SCTP_ABORT flag EINVAL, Expected error*/
+ sinfo->sinfo_flags = SCTP_ABORT;
+ count = sendmsg(sk, &outmessage, flag);
+ if (count != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() with SCTP_ABORT flag - EINVAL");
+
+ sinfo->sinfo_flags = 0;
+
+ test_connect(sk1, (struct sockaddr *) &lstn_addr, len);
+
+ test_sendmsg(sk1, &outmessage, flag, strlen(message)+1);
+
+ close(sk1);
+ acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len);
+
+ /*sendmsg () TEST10:sendmsg on closed association, EPIPE Expected error*/
+ count = sendmsg(acpt1_sk, &outmessage, flag);
+ if (count != -1 || errno != EPIPE)
+ tst_brkm(TBROK, tst_exit, "sendmsg on a closed association "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() on a closed association - EPIPE");
+
+ close(acpt1_sk);
+ close(sk);
+ close(lstn_sk);
+ close(acpt_sk);
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+ flag = MSG_NOSIGNAL;
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &svr_addr;
+ outmessage.msg_namelen = sizeof(svr_addr);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ buffer_rcv = malloc(REALLY_BIG);
+
+ iov_rcv.iov_base = buffer_rcv;
+ iov_rcv.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov_rcv;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ msg_count = strlen(message) + 1;
+
+ /*sendmsg() TEST11: Sending data from server socket to client socket*/
+ count = sendmsg(acpt_sk, &outmessage, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendmsg from accept socket to "
+ "client count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() from accept socket to client - SUCCESS");
+
+ count = test_recvmsg(sk, &inmessage, flag);
+ test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+ outmessage.msg_name = &conn_addr;
+ outmessage.msg_namelen = sizeof(conn_addr);
+ /*sendmsg() TEST12: Sending data from client socket to server socket*/
+ count = sendmsg(sk, &outmessage, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendmsg from client to server "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() from client to server - SUCCESS");
+
+ count = test_recvmsg(acpt_sk, &inmessage, flag);
+ test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+ outmessage.msg_name = &conn_addr;
+ outmessage.msg_namelen = sizeof(conn_addr);
+ close(sk);
+ close(acpt_sk);
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*sendmsg() TEST13: Sending data from unconnected client socket to
+ server socket*/
+ count = sendmsg(sk1, &outmessage, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendmsg from unconnected client to "
+ "server count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() from unconnected clt to server - SUCCESS");
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ count = test_recvmsg(acpt_sk, &inmessage, flag);
+ test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+ test_shutdown(sk1, SHUT_RD);
+
+ /*sendmsg() TEST14: Sending a message on SHUT_RD socket*/
+ count = sendmsg(sk1, &outmessage, flag);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendmsg on a SHUT_RD socket "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendmsg() on a SHUT_RD socket - SUCCESS");
+
+ count = test_recvmsg(acpt_sk, &inmessage, flag);
+ test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0);
+
+ close(sk1);
+ close(lstn_sk);
+ close(acpt_sk);
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sendto.c b/src/func_tests/test_1_to_1_sendto.c
new file mode 100644
index 0000000..56b102a
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sendto.c
@@ -0,0 +1,164 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the sendto () call
+ * for 1-1 style sockets
+ *
+ * TEST1: Sending data from client socket to server socket
+ * TEST2: Sending data from accept (server) socket to client socket
+ * TEST3: Sending data from unconnected client socket to server
+ * TEST4: sending partial data from a buffer
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int msg_count;
+ socklen_t len;
+ int sk,sk1,pf_class,lstn_sk,acpt_sk,flag;
+ char *message = "hello, world!\n";
+ char *message_rcv;
+ int count;
+
+ struct sockaddr_in conn_addr,lstn_addr,svr_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbufferd
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ message_rcv = malloc(512);
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ /*Binding the listen socket*/
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ /*Listening the socket*/
+ test_listen(lstn_sk, 10);
+
+ len = sizeof(struct sockaddr_in);
+ flag = MSG_NOSIGNAL;
+
+ test_connect(sk, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ msg_count = strlen(message) + 1;
+
+ /*sendto() TEST1: Sending data from client socket to server socket*/
+ count = sendto(sk, message, msg_count, flag,
+ (const struct sockaddr *) &conn_addr, len);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendto from client to server "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendto() from client to server - SUCCESS");
+
+ test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+ strncpy(message_rcv,"\0",512);
+
+ /*sendto() TEST2: Sending data from accept socket to client socket*/
+ count = sendto(acpt_sk, message, msg_count, flag,
+ (const struct sockaddr *) &svr_addr, len);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendto from accept socket to client "
+ "count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendto() from accept socket to client - SUCCESS");
+
+ test_recv(sk, message_rcv, msg_count, flag);
+
+ close(sk);
+ close(acpt_sk);
+
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*sendto() TEST3: Sending data from unconnected client socket to
+ server socket*/
+ count = sendto(sk1, message, msg_count, flag,
+ (const struct sockaddr *) &conn_addr, len);
+ if (count != msg_count)
+ tst_brkm(TBROK, tst_exit, "sendto from unconnected client to "
+ "server count:%d, errno:%d", count, errno);
+
+ tst_resm(TPASS, "sendto() from unconnected client to server - SUCCESS");
+
+ acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
+
+ test_recv(acpt_sk, message_rcv, msg_count, flag);
+
+ /*send() TEST4: Sending less number of data from the buffer*/
+ /*Sending only 5 bytes so that only hello is received*/
+ test_sendto(sk1, message, 5, flag, (const struct sockaddr *)&conn_addr,
+ len);
+ test_recv(acpt_sk, message_rcv, 5, flag);
+
+ tst_resm(TPASS, "sendto() partial data from a buffer - SUCCESS");
+
+ close(sk1);
+ close(lstn_sk);
+ close(acpt_sk);
+ return 0;
+
+}
diff --git a/src/func_tests/test_1_to_1_shutdown.c b/src/func_tests/test_1_to_1_shutdown.c
new file mode 100644
index 0000000..26c5b15
--- /dev/null
+++ b/src/func_tests/test_1_to_1_shutdown.c
@@ -0,0 +1,228 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the shutdown() call for 1-1 style sockets
+ *
+ * TEST1: Bad socket descriptor
+ * TEST2: Invalid socket
+ * TEST3: shutdown with SHUT_WR flag to disable new send
+ * TEST4: shutdown with SHUT_RD flag to disable new receive
+ * TEST5: shutdown with SHUT_RDWR flag to disable new receive/send
+ * TEST6: Unconnected socket
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/socket.h>
+#include <netinet/sctp.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int clnt_sk[MAX_CLIENTS], acpt_sk[MAX_CLIENTS],sk;
+ int lstn_sk;
+ struct sockaddr_in lstn_addr, acpt_addr;
+ socklen_t addrlen;
+ int error, i;
+ char *message = "hello, world!\n";
+ char msgbuf[100];
+ int pf_class;
+ int fd, err_no = 0;
+ char filename[21];
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+ pf_class = PF_INET;
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+
+ test_listen(lstn_sk, MAX_CLIENTS);
+
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clnt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_connect(clnt_sk[i], (struct sockaddr *)&lstn_addr,
+ sizeof(lstn_addr));
+ }
+
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ addrlen = sizeof(acpt_addr);
+ acpt_sk[i] = test_accept(lstn_sk, (struct sockaddr *)&acpt_addr,
+ &addrlen);
+ }
+
+ /*shutdown() TEST1: Bad socket descriptor, EBADF Expected error*/
+ error = shutdown(-1, SHUT_WR);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "shutdown with a bad socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "shutdown() with a bad socket descriptor - EBADF");
+
+ /*shutdown() TEST2: Invalid socket, ENOTSOCK Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = shutdown(fd, SHUT_WR);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "shutdown with an invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "shutdown() with an invalid socket - ENOTSOCK");
+
+ errno = 0;
+ /*Do a send first before doing shutdown*/
+ test_send(acpt_sk[0], message, strlen(message), 0);
+
+ /*shutdown() TEST3: shutdown with SHUT_WR flag to disable new send*/
+ error = shutdown(clnt_sk[0], SHUT_WR);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "shutdown with SHUT_WR flag "
+ "error:%d, errno:%d", error, errno);
+
+ /* Reading on a socket that has received SHUTDOWN should return 0
+ * indicating EOF.
+ */
+ error = recv(acpt_sk[0], msgbuf, 100, 0);
+ if ((error != 0) || (errno != 0))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+ "error:%d, errno:%d", error, errno);
+
+ /* Read the pending message on clnt_sk[0] that was received before
+ * SHUTDOWN call.
+ */
+ test_recv(clnt_sk[0], msgbuf, 100, 0);
+
+ /* No more messages and the association is SHUTDOWN, should fail. */
+ error = recv(clnt_sk[0], msgbuf, 100, 0);
+ if ((error != -1) || (errno != ENOTCONN))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_WR socket with no "
+ "messages error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "shutdown() with SHUT_WR flag - SUCCESS");
+
+ errno = 0;
+
+ /*shutdown() TEST4: shutdown with SHUT_RD flag to disable new receive*/
+ test_shutdown(clnt_sk[1], SHUT_RD);
+
+ error = recv(clnt_sk[1], msgbuf, 100, 0);
+ if ((error != 0) || (errno != 0))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+ "error:%d, errno:%d", error, errno);
+
+ /* Sending a message on SHUT_RD socket. */
+ error = test_send(clnt_sk[1], message, strlen(message), 0);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "send on a SHUT_RD socket "
+ "error:%d, errno:%d", error, errno);
+
+ /* Receive the message sent on SHUT_RD socket. */
+ test_recv(acpt_sk[1], msgbuf, 100, 0);
+
+ /* Send a message to the SHUT_RD socket. */
+ test_send(acpt_sk[1], message, strlen(message), 0);
+
+ /* We should not receive the message as the socket is SHUT_RD */
+ error = recv(clnt_sk[1], msgbuf, 100, 0);
+ if ((error != 0) || (errno != 0))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "shutdown() with SHUT_RD flag - SUCCESS");
+
+ /*shutdown() TEST5: shutdown with SHUT_RDWR flag to disable new
+ receive/send*/
+ test_shutdown(clnt_sk[2], SHUT_RDWR);
+
+ error = recv(acpt_sk[2], msgbuf, 100, 0);
+ if ((error != 0) || (errno != 0))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+ "error:%d, errno:%d", error, errno);
+
+ error = recv(clnt_sk[2], msgbuf, 100, 0);
+ if ((error != 0) || (errno != 0))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "shutdown() with SHUT_RDWR flag - SUCCESS");
+
+ /*shutdown() TEST6: Unconnected socket, ENOTCONN Expected error*/
+ error = shutdown(sk, SHUT_RD);
+ if ((error != -1) || (errno != ENOTCONN))
+ tst_brkm(TBROK, tst_exit, "shutdown on an unconnected socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "shutdown() on an unconnected socket - SUCCESS");
+
+ for (i = 0; i < MAX_CLIENTS; i++)
+ close(clnt_sk[i]);
+ for (i = 0; i < MAX_CLIENTS; i++)
+ close(acpt_sk[i]);
+
+
+ close(lstn_sk);
+ close(sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_socket_bind_listen.c b/src/func_tests/test_1_to_1_socket_bind_listen.c
new file mode 100644
index 0000000..06c6847
--- /dev/null
+++ b/src/func_tests/test_1_to_1_socket_bind_listen.c
@@ -0,0 +1,288 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test the socket (), bind () and listen () for
+ * 1-1 style sockets
+ *
+ * socket () Tests:
+ * ---------------
+ * TEST1: Invalid domain
+ * TEST2: Invalid type
+ * TEST3: Opening a TCP style socket
+ *
+ * bind () Tests:
+ * -------------
+ * TEST4: Invalid address
+ * TEST5: Invalid address length
+ * TEST6: Invalid socket descriptor
+ * TEST7: Invalid host name
+ * TEST8: On a socket that is already bound
+ * TEST9: On reserved ports
+ * TEST10: INADDR_ANY address and non-zero port
+ * TEST11: INADDR_ANY address and zero port
+ * TEST12: Local address and zero port
+ *
+ * listen () Tests:
+ * ---------------
+ * TEST13: Bad socket descriptor
+ * TEST14: Invalid socket
+ * TEST15: Listening a bound socket
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+#define SCTP_RESERVED_PORT 7
+#define SCTP_INV_LOOPBACK "172.31.43.112"
+
+char *TCID = __FILE__;
+int TST_TOTAL = 15;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int sk,pf_class;
+ int error = 0;
+ int uid;
+ int fd, err_no = 0;
+ char filename[21];
+
+ struct sockaddr_in bind_addr;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ /* socket() TEST1: Invalid domain, EAFNOSUPPORT Expected error */
+ sk = socket(-1, SOCK_STREAM, IPPROTO_SCTP);
+ if (sk != -1 || errno != EAFNOSUPPORT)
+ tst_brkm(TBROK, tst_exit, "socket() with invalid domain "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "socket() with invalid domain - EAFNOSUPPORT");
+
+ /*socket() TEST2 : Invalid type, EINVAL Expected error*/
+ sk = socket(pf_class, -1, IPPROTO_SCTP);
+ if (sk != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "socket() with invalid type "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "socket() with invalid type - EINVAL");
+
+ /*socket() TEST3: opening a socket*/
+ sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ if (sk < 0)
+ tst_brkm(TBROK, tst_exit, "valid socket() call "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "socket() - SUCCESS");
+
+ /*bind() TEST4: Invalid structure, EFAULT Expected error */
+ error = bind(sk, (struct sockaddr *)-1, sizeof(struct sockaddr_in));
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "bind() with invalid address ptr "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with invalid address ptr - EFAULT");
+
+ /*bind() TEST5: Invalid address length, EINVAL Expect error*/
+ bind_addr.sin_family = AF_INET;
+ bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ bind_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr)-2);
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "bind() with invalid address length "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with invalid address length - EINVAL");
+
+ /*bind() TEST6: Invalid socket descriptor, ENOTSOCK Expect Error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = bind(fd, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "bind() with invalid socket "
+ "descriptor error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "bind() with invalid socket descriptor - ENOTSOCK");
+
+ /*bind() TEST7: Invalid host name, EADDRNOTAVAIL Expect Error*/
+ /*Assigning invalid host name*/
+ bind_addr.sin_addr.s_addr = inet_addr(SCTP_INV_LOOPBACK);
+ error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+ if (error != -1 || errno != EADDRNOTAVAIL)
+ tst_brkm(TBROK, tst_exit, "bind() with invalid local "
+ "address error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with invalid local address - EADDRNOTAVAIL");
+
+ /*bind() TEST8: Bind on a socket that has already called bind
+ EINAVL, Expected error*/
+ bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ /*Calling bind first time, it should pass*/
+ test_bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+
+ error = bind(sk, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
+ if (error != -1 || errno != EINVAL)
+ tst_brkm(TBROK, tst_exit, "bind() on an already bound socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() on an already bound socket - EINVAL");
+
+ /*Closing the socket which succeed in bind() */
+ close(sk);
+
+ /*Opening the socket again for further test*/
+ sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*bind() TEST9: Bind on reserved ports EACCES, Expected error*/
+ /*Assigning a reserved port*/
+ uid = getuid();
+ if (uid != 0) {
+ bind_addr.sin_port = htons(SCTP_RESERVED_PORT);
+ error = bind(sk, (struct sockaddr *) &bind_addr,
+ sizeof(bind_addr));
+ if (error != -1 || errno != EACCES)
+ tst_brkm(TBROK, tst_exit, "bind() on reserverd port "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() on reserved port - EACCESS");
+ }
+
+ /*bind() TEST10: INADDR_ANY address and non-zero port, bind() should
+ succeed*/
+ bind_addr.sin_addr.s_addr = INADDR_ANY;
+ bind_addr.sin_port = htons(SCTP_TESTPORT_1);
+ error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+ if ( error < 0 )
+ tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and "
+ "non-zero port error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with INADDR_ANY address and non-zero port - "
+ "SUCCESS");
+
+ /*Closing the socket which succeed in bind() */
+ close(sk);
+
+ /*Opening the socket again for further test*/
+ sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*bind() TEST11: INADDR_ANY address and zero port, bind() should
+ succeed*/
+ bind_addr.sin_port = 0;
+ error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+ if ( error < 0 )
+ tst_brkm(TBROK, tst_exit, "bind() with INADDR_ANY address and "
+ "zero port error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with INADDR_ANY address and zero port - "
+ "SUCCESS");
+
+ /*Closing the socket which succeed in bind() */
+ close(sk);
+
+ /*Opening the socket again for further test*/
+ sk = socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*bind() TEST12: local address and zero port, bind() should
+ succeed*/
+ bind_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ bind_addr.sin_port = 0;
+ error = bind(sk, (struct sockaddr *) &bind_addr,sizeof(bind_addr));
+ if ( error < 0 )
+ tst_brkm(TBROK, tst_exit, "bind() with local address and "
+ "zero port error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "bind() with local address and zero port - "
+ "SUCCESS");
+
+ /*listen() TEST13: Bad socket descriptor EBADF, Expected error*/
+ error = listen(-1, 3);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "listen() with bad socket descriptor "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "listen() with bad socket descriptor - EBADF");
+
+ /*listen() TEST14: Invalid socket ENOTSOCK, Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = listen(fd, 3);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "listen() with invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "listen() with invalid socket - ENOTSOCK");
+
+ /*listen() TEST15:listen on a bound socket, should succeed*/
+ error = listen(sk, 3);
+ if ( error < 0 )
+ tst_brkm(TBROK, tst_exit, "listen() on a bound socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "listen() on a bound socket - SUCCESS");
+
+ close(sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_sockopt.c b/src/func_tests/test_1_to_1_sockopt.c
new file mode 100644
index 0000000..49f4eaf
--- /dev/null
+++ b/src/func_tests/test_1_to_1_sockopt.c
@@ -0,0 +1,434 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file has test cases to test negative scenarios for getsockopt ()
+ * setsockopt () call for 1-1 style sockets
+ *
+ * setsockopt () Tests:
+ * -------------------
+ * TEST1: setsockopt: Bad socket descriptor
+ * TEST2: setsockopt: Invalid socket
+ * TEST3: setsockopt: Invalid level
+ * TEST4: setsockopt: Invalid option buffer
+ * TEST5: setsockopt: Invalid option name
+ * TEST6: getsockopt: Bad socket descriptor
+ * TEST7: getsockopt: Invalid socket
+ * TEST8: getsockopt: Invalid option buffer
+ * TEST9: getsockopt: Invalid option name
+ *
+ * TEST10: getsockopt: SCTP_INITMSG
+ * TEST11: setsockopt: SCTP_INITMSG
+ * TEST12: setsockopt: SO_LINGER
+ * TEST13: getsockopt: SO_LINGER
+ * TEST14: getsockopt: SO_RCVBUF
+ * TEST15: getsockopt: SCTP_STATUS
+ * TEST16: setsockopt: SO_RCVBUF
+ * TEST17: setsockopt: SO_SNDBUF
+ * TEST18: getsockopt: SO_SNDBUF
+ * TEST19: getsockopt: SCTP_PRIMARY_ADDR
+ * TEST20: setsockopt: SCTP_PRIMARY_ADDR
+ * TEST21: getsockopt: SCTP_ASSOCINFO
+ * TEST22: setsockopt: SCTP_ASSOCINFO
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 22;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+ int error;
+ socklen_t len;
+ int sk, sk1, sk2, acpt_sk, pf_class;
+ struct sctp_rtoinfo grtinfo;
+ struct sockaddr_in lstn_addr, conn_addr;
+ struct sctp_initmsg ginmsg; /*get the value for SCTP_INITMSG*/
+ struct sctp_initmsg sinmsg; /*set the value for SCTP_INITMSG*/
+ struct linger slinger; /*SO_LINGER structure*/
+ struct linger glinger; /*SO_LINGER structure*/
+ struct sockaddr_in addr;
+ struct sockaddr_in *gaddr;
+ struct sctp_status gstatus; /*SCTP_STATUS option*/
+ int rcvbuf_val_get, rcvbuf_val_set; /*get and set var for SO_RCVBUF*/
+ int sndbuf_val_get, sndbuf_val_set;/*get and set var for SO_SNDBUF*/
+ struct sctp_prim gprimaddr;/*SCTP_PRIMARY_ADDR get*/
+ struct sctp_prim sprimaddr;/*SCTP_PRIMARY_ADDR set*/
+ struct sctp_assocparams sassocparams; /* SCTP_ASSOCPARAMS set */
+ struct sctp_assocparams gassocparams; /* SCTP_ASSOCPARAMS get */
+ int fd, err_no = 0;
+ char filename[21];
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ pf_class = PF_INET;
+
+ sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /*setsockopt() TEST1: Bad socket descriptor EBADF, Expected error*/
+ error = setsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "setsockopt with a bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() with a bad socket descriptor - EBADF");
+
+ /*setsockopt() TEST2: Invalid socket ENOTSOCK, Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = setsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "setsockopt with an invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "setsockopt() with an invalid socket - ENOTSOCK");
+
+ /*setsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
+ error = setsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
+ if (error != -1 || errno != ENOPROTOOPT)
+ tst_brkm(TBROK, tst_exit, "setsockopt with invalid level "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() with an invalid level - ENOPROTOOPT");
+
+ /*setsockopt() TEST4: Invalid option buffer EFAULT, Expected error*/
+ error = setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO,
+ (const struct sctp_rtoinfo *)-1, sizeof(struct sctp_rtoinfo));
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
+ "buffer error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() with invalid option buffer - EFAULT");
+
+ /*setsockopt() TEST5: Invalid option Name EOPNOTSUPP, Expected error*/
+ error = setsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, 0, 0);
+ if (error != -1 || errno != EOPNOTSUPP)
+ tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
+ "name error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() with invalid option name - EOPNOTSUPP");
+
+ /*getsockopt() TEST6: Bad socket descriptor EBADF, Expected error*/
+ error = getsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "getsockopt with a bad socket "
+ "descriptor error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() with a bad socket descriptor - EBADF");
+
+ /*getsockopt() TEST7: Invalid socket ENOTSOCK, Expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = getsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "getsockopt with an invalid socket "
+ "error:%d, errno:%d", error, err_no);
+
+ tst_resm(TPASS, "getsockopt() with an invalid socket - ENOTSOCK");
+#if 0
+ /*getsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
+ /*I have commented this test case because it is returning EOPNOTSUPP.
+ When I checked the code there also it is returning EOPNOTSUPP. As this
+ is not specific to TCP style, I do not want to do the code change*/
+
+ error = getsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
+ if (error != -1 || errno != ENOPROTOOPT)
+ tst_brkm(TBROK, tst_exit, "getsockopt with invalid level "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() with an invalid level - ENOPROTOOPT");
+#endif
+ len = sizeof(struct sctp_rtoinfo);
+
+ /*getsockopt() TEST8: Invalid option buffer EFAULT, Expected error*/
+ error = getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO,
+ (struct sctp_rtoinfo *)-1, &len);
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
+ "buffer error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() with invalid option buffer - EFAULT");
+
+ /*getsockopt() TEST9: Invalid option Name EOPNOTSUPP, Expected error*/
+ error = getsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, &grtinfo, &len);
+ if (error != -1 || errno != EOPNOTSUPP)
+ tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
+ "name error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() with invalid option name - EOPNOTSUPP");
+
+ close(sk);
+
+ sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ len = sizeof(struct sctp_initmsg);
+
+ /* TEST10: Test cases for getsockopt SCTP_INITMSG */
+ test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
+
+ tst_resm(TPASS, "getsockopt() SCTP_INITMSG - SUCCESS");
+
+ sinmsg.sinit_num_ostreams = 5;
+ sinmsg.sinit_max_instreams = 5;
+ sinmsg.sinit_max_attempts = 3;
+ sinmsg.sinit_max_init_timeo = 30;
+ /* TEST11: Test case for setsockopt SCTP_INITMSG */
+ test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, sizeof(sinmsg));
+
+ test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
+
+ if (sinmsg.sinit_num_ostreams != ginmsg.sinit_num_ostreams &&
+ sinmsg.sinit_max_instreams != ginmsg.sinit_max_instreams &&
+ sinmsg.sinit_max_attempts != ginmsg.sinit_max_attempts &&
+ sinmsg.sinit_max_init_timeo != ginmsg.sinit_max_init_timeo)
+ tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
+ "compare failed");
+
+ tst_resm(TPASS, "setsockopt() SCTP_INITMSG - SUCCESS");
+
+ /*Now get the values on different endpoint*/
+ test_getsockopt(sk2, SCTP_INITMSG, &ginmsg, &len);
+
+ /*Comparison should not succeed here*/
+ if (sinmsg.sinit_num_ostreams == ginmsg.sinit_num_ostreams &&
+ sinmsg.sinit_max_instreams == ginmsg.sinit_max_instreams &&
+ sinmsg.sinit_max_attempts == ginmsg.sinit_max_attempts &&
+ sinmsg.sinit_max_init_timeo == ginmsg.sinit_max_init_timeo)
+ tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
+ "unexpected compare success");
+
+ /* SO_LINGER Test with l_onff = 0 and l_linger = 0 */
+ slinger.l_onoff = 0;
+ slinger.l_linger = 0;
+ test_bind(sk1, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
+ test_listen(sk1, 10 );
+ len = sizeof(struct sockaddr_in);
+ test_connect(sk2, (struct sockaddr *) &conn_addr, len);
+
+ acpt_sk = test_accept(sk1, (struct sockaddr *)&addr, &len);
+
+ len = sizeof(struct linger);
+ /* TEST12: Test case for setsockopt SO_LINGER */
+ error = setsockopt(sk2, SOL_SOCKET, SO_LINGER, &slinger, len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SO_LINGER "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() SO_LINGER - SUCCESS");
+
+ /* TEST13: Test case for getsockopt SO_LINGER */
+ error = getsockopt(sk2, SOL_SOCKET, SO_LINGER, &glinger, &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SO_LINGER "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SO_LINGER - SUCCESS");
+
+ if (slinger.l_onoff != glinger.l_onoff ||
+ slinger.l_linger != glinger.l_linger)
+ tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SO_LINGER "
+ "compare failed");
+
+ /*First gets the default SO_RCVBUF value and comapres with the
+ value obtained from SCTP_STATUS*/
+ len = sizeof(int);
+ /* TEST14: Test case for getsockopt SO_RCVBUF */
+ error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SO_RCVBUF - SUCCESS");
+
+ len = sizeof(struct sctp_status);
+ /* TEST15: Test case for getsockopt SCTP_STATUS */
+ error = getsockopt(sk2, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_STATUS "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SCTP_STATUS - SUCCESS");
+
+ /* Reducing the SO_RCVBUF value using setsockopt() */
+ /* Upstream has changed the MIN_RCVBUF (2048 + sizeof(struct sk_buff)) */
+ len = sizeof(int);
+ rcvbuf_val_set = 2048;
+ /* TEST16: Test case for setsockopt SO_RCVBUF */
+ error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_set, len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SO_RCVBUF "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() SO_RCVBUF - SUCCESS");
+
+ error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
+ "error:%d, errno:%d", error, errno);
+
+ if ((2 * rcvbuf_val_set) != rcvbuf_val_get)
+ tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
+ "got value differs Set Value=%d Get Value=%d",
+ (2*rcvbuf_val_set), rcvbuf_val_get);
+
+ sndbuf_val_set = 2304;
+ /* TEST17: Test case for setsockopt SO_SNDBUF */
+ error = setsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_set, len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SO_SNDBUF "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() SO_SNDBUF - SUCCESS");
+
+ /* TEST18: Test case for getsockopt SO_SNDBUF */
+ error = getsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_get, &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SO_SNDBUF "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SO_SNDBUF - SUCCESS");
+
+ if ((2 * sndbuf_val_set) != sndbuf_val_get)
+ tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
+ "got value differs Set Value=%d Get Value=%d\n",
+ (2*sndbuf_val_set), sndbuf_val_get);
+
+
+ /* Getting the primary address using SCTP_PRIMARY_ADDR */
+ len = sizeof(struct sctp_prim);
+ /* TEST19: Test case for getsockopt SCTP_PRIMARY_ADDR */
+ error = getsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &gprimaddr,
+ &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
+
+ gaddr = (struct sockaddr_in *) &gprimaddr.ssp_addr;
+ if(htons(gaddr->sin_port) != lstn_addr.sin_port &&
+ gaddr->sin_family != lstn_addr.sin_family &&
+ gaddr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR value "
+ "mismatch");
+
+ memcpy(&sprimaddr, &gprimaddr, sizeof(struct sctp_prim));
+
+ /* TEST20: Test case for setsockopt SCTP_PRIMARY_ADDR */
+ error = setsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &sprimaddr,
+ len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SCTP_PRIMARY_ADDR "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
+
+ /* TEST21: Test case for getsockopt SCTP_PRIMARY_ADDR */
+ /* Getting the association info using SCTP_ASSOCINFO */
+ len = sizeof(struct sctp_assocparams);
+ error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
+ &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt() SCTP_ASSOCINFO - SUCCESS");
+
+ /* TEST21: Test case for setsockopt SCTP_ASSOCINFO */
+ memcpy(&sassocparams, &gassocparams, sizeof(struct sctp_assocparams));
+ sassocparams.sasoc_asocmaxrxt += 5;
+ sassocparams.sasoc_cookie_life += 10;
+
+ error = setsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &sassocparams,
+ len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "setsockopt SCTP_ASSOCINFO "
+ "error:%d, errno:%d", error, errno);
+
+ error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
+ &len);
+ if (error < 0)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
+ "error:%d, errno:%d", error, errno);
+
+ if (sassocparams.sasoc_asocmaxrxt != gassocparams.sasoc_asocmaxrxt ||
+ sassocparams.sasoc_cookie_life != gassocparams.sasoc_cookie_life)
+ tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO value "
+ "mismatch");
+ tst_resm(TPASS, "setsockopt() SCTP_ASSOCINFO - SUCCESS");
+
+ close(sk2);
+ close(sk1);
+ close(acpt_sk);
+
+ return 0;
+}
diff --git a/src/func_tests/test_1_to_1_threads.c b/src/func_tests/test_1_to_1_threads.c
new file mode 100644
index 0000000..e2a7eee
--- /dev/null
+++ b/src/func_tests/test_1_to_1_threads.c
@@ -0,0 +1,196 @@
+/* SCTP kernel Implementation
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This file does send and receive for 500 threads on a unique association for
+ * THREAD_SND_RCV_LOOPS = 10 many times. To change the number of threads
+ * change the THREADS valuen and loop change the THREAD_SND_RCV_LOOPS.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release
+ *
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sys/uio.h>
+#include <linux/socket.h>
+#include <sctputil.h>
+
+#define THREADS 10 /* FIXME should be 500 instead of 10 */
+#define THREAD_SND_RCV_LOOPS 10
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int client_sk;
+int server_sk;
+int acpt_sk;
+struct sockaddr_in conn_addr;
+char *message = "hello, world!\n";
+
+void
+t_recv(void) {
+ int cnt;
+ struct msghdr inmessage;
+ struct iovec iov;
+ char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ char * buffer;
+
+ memset(&inmessage, 0, sizeof(inmessage));
+ buffer = malloc(100);
+
+ iov.iov_base = buffer;
+ iov.iov_len = 100;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ cnt = test_recvmsg(acpt_sk,&inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, cnt, strlen(message) + 1, MSG_EOR,
+ 0, 0);
+}
+
+void
+t_send(void) {
+ struct msghdr outmessage;
+ struct sctp_sndrcvinfo *sinfo;
+ struct cmsghdr *cmsg;
+ struct iovec out_iov;
+ char outcmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &conn_addr;
+ outmessage.msg_namelen = sizeof(conn_addr);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = (strlen(message) + 1);
+
+ test_sendmsg(client_sk, &outmessage, 0, strlen(message)+1);
+}
+
+void *relay(void *arg)
+{
+ int id = *(int *) arg;
+
+ if (id == 0) {
+ t_send();
+ } else {
+ t_recv();
+ t_send();
+ }
+
+ pthread_exit(NULL);
+}
+
+int
+main(void)
+{
+
+ int cnt,i;
+ int pth[THREADS];
+ pthread_t thread[THREADS];
+ int status;
+ int exit_status;
+ void * result;
+ pthread_attr_t attr;
+ struct sockaddr_in lstn_addr;
+ socklen_t len = sizeof(struct sockaddr_in);
+ struct sockaddr_in svr_addr;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ server_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+ client_sk = test_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ lstn_addr.sin_family = AF_INET;
+ lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ conn_addr.sin_family = AF_INET;
+ conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ conn_addr.sin_port = htons(SCTP_TESTPORT_1);
+
+ test_bind(server_sk, (struct sockaddr *)&lstn_addr,
+ sizeof(struct sockaddr_in));
+
+ test_listen(server_sk,10);
+
+ test_connect(client_sk,(struct sockaddr *)&conn_addr,len);
+
+ acpt_sk = test_accept(server_sk, (struct sockaddr *)&svr_addr, &len);
+
+ for ( i = 0; i < THREAD_SND_RCV_LOOPS; i++ ) {
+ for (cnt = 0; cnt < THREADS; cnt++) {
+ pth[cnt] = cnt;
+ status = pthread_create(&thread[cnt], &attr, relay, &pth[cnt]);
+ if (status)
+ tst_brkm(TBROK, tst_exit, "pthread_create "
+ "failed status:%d, errno:%d", status,
+ errno);
+ }
+
+ pthread_attr_destroy(&attr);
+ for (cnt = 0; cnt < THREADS ; cnt++) {
+ exit_status = pthread_join (thread[cnt], &result);
+ if (exit_status == -1)
+ tst_brkm(TBROK, tst_exit, "pthread_join "
+ "Thread #%d exited with status:%d",
+ cnt, exit_status);
+ }
+ }
+
+ tst_resm(TPASS, "send and receive data across multiple threads - "
+ "SUCCESS");
+
+ return 0;
+}
diff --git a/src/func_tests/test_assoc_abort.c b/src/func_tests/test_assoc_abort.c
new file mode 100644
index 0000000..f8019c7
--- /dev/null
+++ b/src/func_tests/test_assoc_abort.c
@@ -0,0 +1,243 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intle.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the ungraceful abort of an
+ * association.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk[MAX_CLIENTS];
+ sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+ sctp_assoc_t svr_associd[MAX_CLIENTS];
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ int error;
+ uint32_t ppid;
+ uint32_t stream;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ int i;
+ char *message = "hello, world!\n";
+ struct sctp_status status;
+ socklen_t status_len;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+ test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind all the client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ clt_loop[i].v4.sin_family = AF_INET;
+ clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+ test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+ test_enable_assoc_change(clt_sk[i]);
+ }
+
+ /* Build up a msghdr structure we can use for all sending. */
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ out_iov.iov_base = message;
+ out_iov.iov_len = strlen(message) + 1;
+
+ /* Send the first message from all the clients to the server. This
+ * will create the associations.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message) + 1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on all client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ }
+
+ /* Get the communication up message and the data message on the
+ * server sockets for all the clients.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd[i] = sac->sac_assoc_id;
+ }
+
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ outmessage.msg_iov = NULL;
+ outmessage.msg_iovlen = 0;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_flags |= SCTP_ABORT;
+
+ /* Shutdown all the associations of the server socket in a loop. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ sinfo->sinfo_assoc_id = svr_associd[i];
+
+ /* Verify that the association is present. */
+ memset(&status, 0, sizeof(struct sctp_status));
+ status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+ status_len = sizeof(struct sctp_status);
+ error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+ &status, &status_len);
+ if (error)
+ tst_brkm(TBROK, tst_exit,
+ "getsockopt(SCTP_STATUS): %s",
+ strerror(errno));
+
+ /* Call sendmsg() to abort the association. */
+ test_sendmsg(svr_sk, &outmessage, 0, 0);
+
+ /* Verify that the association is no longer present. */
+ memset(&status, 0, sizeof(struct sctp_status));
+ status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+ status_len = sizeof(struct sctp_status);
+ error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+ &status, &status_len);
+ if ((error != -1) && (errno != EINVAL))
+ tst_brkm(TBROK, tst_exit,
+ "getsockopt(SCTP_STATUS) "
+ "error:%d errno:%d", error, errno);
+ }
+
+ close(svr_sk);
+
+ /* Get the COMM_LOST notification. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change)+4,
+ SCTP_ASSOC_CHANGE, SCTP_COMM_LOST);
+
+ close(clt_sk[i]);
+ }
+
+ tst_resm(TPASS, "ABORT an association using SCTP_ABORT");
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_assoc_shutdown.c b/src/func_tests/test_assoc_shutdown.c
new file mode 100644
index 0000000..a007117
--- /dev/null
+++ b/src/func_tests/test_assoc_shutdown.c
@@ -0,0 +1,245 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the graceful shutdown of an
+ * association.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk[MAX_CLIENTS];
+ sctp_assoc_t svr_associd[MAX_CLIENTS];
+ sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ int error;
+ uint32_t ppid;
+ uint32_t stream;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ int i;
+ char *message = "hello, world!\n";
+ struct sctp_status status;
+ socklen_t status_len;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+ test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind all the client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_sk[i] = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ clt_loop[i].v4.sin_family = AF_INET;
+ clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+ test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+ test_enable_assoc_change(clt_sk[i]);
+ }
+
+ /* Build up a msghdr structure we can use for all sending. */
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ out_iov.iov_base = message;
+ out_iov.iov_len = strlen(message) + 1;
+
+ /* Send the first message from all the clients to the server. This
+ * will create the associations.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on all client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ }
+
+ /* Get the communication up message and the data message on the
+ * server sockets for all the clients.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message)+1,
+ MSG_EOR, stream, ppid);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd[i] = sac->sac_assoc_id;
+ }
+
+ /* Build up a msghdr structure we can use for all sending. */
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ outmessage.msg_iov = NULL;
+ outmessage.msg_iovlen = 0;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_flags |= SCTP_EOF;
+
+ /* Shutdown all the associations of the server socket in a loop. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ sinfo->sinfo_assoc_id = svr_associd[i];
+
+ /* Verify that the association is present. */
+ memset(&status, 0, sizeof(struct sctp_status));
+ status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+ status_len = sizeof(struct sctp_status);
+ error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+ &status, &status_len);
+ if (error)
+ tst_brkm(TBROK, tst_exit,
+ "getsockopt(SCTP_STATUS): %s",
+ strerror(errno));
+
+ /* Call sendmsg() to shutdown the association. */
+ test_sendmsg(svr_sk, &outmessage, 0, 0);
+
+ /* Verify that the association is no longer present. */
+ memset(&status, 0, sizeof(struct sctp_status));
+ status.sstat_assoc_id = sinfo->sinfo_assoc_id;
+ status_len = sizeof(struct sctp_status);
+ error = getsockopt(svr_sk, SOL_SCTP, SCTP_STATUS,
+ &status, &status_len);
+ if ((error != -1) && (errno != EINVAL))
+ tst_brkm(TBROK, tst_exit,
+ "getsockopt(SCTP_STATUS) "
+ "error:%d errno:%d", error, errno);
+ }
+
+ close(svr_sk);
+
+ /* Get the shutdown complete notification. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE,
+ SCTP_SHUTDOWN_COMP);
+
+ close(clt_sk[i]);
+ }
+
+ tst_resm(TPASS, "Graceful shutdown of associations using SCTP_EOF");
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_autoclose.c b/src/func_tests/test_autoclose.c
new file mode 100644
index 0000000..e65fac0
--- /dev/null
+++ b/src/func_tests/test_autoclose.c
@@ -0,0 +1,167 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a Functional Test to verify autoclose functionality and the
+ * socket option SCTP_AUTOCLOSE that can be used to specify the duration in
+ * which an idle association is automatically closed.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 1;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop1, loop2;
+ struct msghdr inmessage, outmessage;
+ struct iovec iov, out_iov;
+ int error;
+ char *big_buffer;
+ char *message = "hello, world!\n";
+ uint32_t autoclose;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk1);
+ test_enable_assoc_change(sk2);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ /* Mark sk2 as being able to accept new associations. */
+ test_listen(sk2, 1);
+
+ /* Set the autoclose duration for the associations created on sk1
+ * and sk2 to be 5 seconds.
+ */
+ autoclose = 5;
+ test_setsockopt(sk1, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose));
+ test_setsockopt(sk2, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose));
+
+ /* Send the first message. This will create the association. */
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &loop2;
+ outmessage.msg_namelen = sizeof(loop2);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+
+ test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = NULL;
+
+ /* Get the communication up message on sk2. */
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Get the communication up message on sk1. */
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Get the first message which was sent. */
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR|MSG_CTRUNC, 0, 0);
+
+ tst_resm(TINFO, "Waiting for the associations to close automatically "
+ "in 5 secs");
+
+ /* Get the shutdown complete notification from sk1. */
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ /* Get the shutdown complete notification from sk2. */
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ tst_resm(TPASS, "Autoclose of associations");
+
+ /* Shut down the link. */
+ close(sk1);
+ close(sk2);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_basic.c b/src/func_tests/test_basic.c
new file mode 100644
index 0000000..92288b2
--- /dev/null
+++ b/src/func_tests/test_basic.c
@@ -0,0 +1,455 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Hui Huang <hui.huang@nokia.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <samudrala@us.ibm.com>
+ */
+
+/* This is a basic functional test for the SCTP kernel
+ * implementation state machine.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 15;
+int TST_CNT = 0;
+
+int main(void)
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop1;
+ sockaddr_storage_t loop2;
+ sockaddr_storage_t msgname;
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ char *message = "hello, world!\n";
+ char *telephone = "Watson, come here! I need you!\n";
+ char *telephone_resp = "I already brought your coffee...\n";
+ int error, bytes_sent;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ sctp_assoc_t associd1, associd2;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ struct sockaddr *laddrs, *paddrs;
+ int n_laddrs, n_paddrs, i;
+ struct sockaddr *sa_addr;
+ struct sockaddr_in *in_addr;
+ struct sockaddr_in6 *in6_addr;
+ void *addr_buf;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ loop1.v6.sin6_family = AF_INET6;
+ loop1.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+ loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v6.sin6_family = AF_INET6;
+ loop2.v6.sin6_addr = in6addr_loopback;
+ loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+ pf_class = PF_INET;
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = INADDR_ANY;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ tst_resm(TPASS, "socket");
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ tst_resm(TPASS, "bind");
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk1);
+ test_enable_assoc_change(sk2);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_name = &msgname;
+
+ /* Try to read on socket 2. This should fail since we are
+ * neither listening, nor established.
+ */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = recvmsg(sk2, &inmessage, MSG_WAITALL);
+ if (error > 0)
+ tst_brkm(TBROK, tst_exit, "recvmsg on a socket neither"
+ "listening nor established error: %d", error);
+
+ tst_resm(TPASS, "recvmsg on a socket neither listening nor "
+ "established");
+
+ /* Mark sk2 as being able to accept new associations. */
+ error = test_listen(sk2, 1);
+
+ tst_resm(TPASS, "listen");
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &loop2;
+ outmessage.msg_namelen = sizeof(loop2);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+ tst_resm(TPASS, "sendmsg with a valid msg_name");
+
+ /* Get the communication up message on sk2. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_namelen = sizeof(msgname);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if TEST_V6
+
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+ DUMP_CORE;
+ }
+ if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+
+ if (msgname.v6.sin6_family != AF_INET6) {
+ DUMP_CORE;
+ }
+
+ if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
+ sizeof(msgname.v6.sin6_addr))) {
+ DUMP_CORE;
+ }
+#else
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+
+ if (msgname.v4.sin_family != AF_INET) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+ DUMP_CORE;
+ }
+#endif
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd2 = sac->sac_assoc_id;
+
+ /* Get the communication up message on sk1. */
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd1 = sac->sac_assoc_id;
+
+ tst_resm(TPASS, "recvmsg COMM_UP notifications");
+
+ /* Get the first message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_namelen = sizeof(msgname);
+ memset(&msgname, 0, sizeof(msgname));
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+#if TEST_V6
+
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+ DUMP_CORE;
+ }
+ if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+
+ if (msgname.v6.sin6_family != AF_INET6) {
+ DUMP_CORE;
+ }
+
+ if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
+ sizeof(msgname.v6.sin6_addr))) {
+ DUMP_CORE;
+ }
+#else
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_family != AF_INET) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+ DUMP_CORE;
+ }
+#endif
+
+ /* Try to send a message with NULL msg_name and associd, should fail */
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid++;
+ stream++;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = telephone;
+ outmessage.msg_iov->iov_len = strlen(telephone) + 1;
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
+ if ((bytes_sent > 0) || (EPIPE != errno))
+ tst_brkm(TBROK, tst_exit, "sendmsg with NULL associd and "
+ "NULL msg_name error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "sendmsg with NULL associd and NULL msg_name");
+
+ /* Fill in a incorrect assoc_id, which should cause an error. */
+ sinfo->sinfo_assoc_id = associd2;
+ bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
+ if ((bytes_sent > 0) || (EPIPE != errno))
+ tst_brkm(TBROK, tst_exit, "sendmsg with incorrect associd "
+ "error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "sendmsg with incorrect associd");
+
+ /* Fill in a correct assoc_id and get back to the normal testing. */
+ sinfo->sinfo_assoc_id = associd1;
+ /* Send two more messages, to cause a second SACK. */
+ test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1);
+
+ outmessage.msg_name = &loop2;
+ outmessage.msg_namelen = sizeof(loop2);
+ outmessage.msg_iov->iov_base = telephone_resp;
+ outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1);
+
+ tst_resm(TPASS, "sendmsg with valid associd");
+
+ /* Get those two messages. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(telephone) + 1,
+ MSG_EOR, stream, ppid);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1,
+ MSG_EOR, stream, ppid);
+
+ tst_resm(TPASS, "recvmsg");
+
+ n_laddrs = sctp_getladdrs(sk1, associd1, &laddrs);
+ if (n_laddrs <= 0)
+ tst_brkm(TBROK, tst_exit, "sctp_getladdrs: %s",
+ strerror(errno));
+
+ tst_resm(TPASS, "sctp_getladdrs");
+
+ addr_buf = (void *)laddrs;
+ for (i = 0; i < n_laddrs; i++) {
+ sa_addr = (struct sockaddr *)addr_buf;
+ if (AF_INET == sa_addr->sa_family) {
+ in_addr = (struct sockaddr_in *)sa_addr;
+ tst_resm(TINFO, "LOCAL ADDR %d.%d.%d.%d PORT %d",
+ NIPQUAD(in_addr->sin_addr),
+ ntohs(in_addr->sin_port));
+ addr_buf += sizeof(struct sockaddr_in);
+ } else {
+ in6_addr = (struct sockaddr_in6 *)sa_addr;
+ tst_resm(TINFO,
+ "LOCAL ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
+ NIP6(in6_addr->sin6_addr),
+ ntohs(in6_addr->sin6_port));
+ addr_buf += sizeof(struct sockaddr_in6);
+ }
+ }
+
+ sctp_freeladdrs(laddrs);
+
+ tst_resm(TPASS, "sctp_freeladdrs");
+
+ n_paddrs = sctp_getpaddrs(sk1, associd1, &paddrs);
+ if (n_paddrs <= 0)
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s",
+ strerror(errno));
+
+ tst_resm(TPASS, "sctp_getpaddrs");
+
+ addr_buf = (void *)paddrs;
+ for (i = 0; i < n_paddrs; i++) {
+ sa_addr = (struct sockaddr *)addr_buf;
+ if (AF_INET == sa_addr->sa_family) {
+ in_addr = (struct sockaddr_in *)sa_addr;
+ tst_resm(TINFO, "PEER ADDR %d.%d.%d.%d PORT %d",
+ NIPQUAD(in_addr->sin_addr),
+ ntohs(in_addr->sin_port));
+ addr_buf += sizeof(struct sockaddr_in);
+ } else {
+ in6_addr = (struct sockaddr_in6 *)sa_addr;
+ tst_resm(TINFO,
+ "PEER ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
+ NIP6(in6_addr->sin6_addr),
+ ntohs(in6_addr->sin6_port));
+ addr_buf += sizeof(struct sockaddr_in6);
+ }
+ }
+
+ sctp_freepaddrs(paddrs);
+
+ tst_resm(TPASS, "sctp_freepaddrs");
+
+ /* Shut down the link. */
+ close(sk1);
+
+ /* Get the shutdown complete notification. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ inmessage.msg_namelen = sizeof(msgname);
+ memset(&msgname, 0, sizeof(msgname));
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+#if TEST_V6
+
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
+ DUMP_CORE;
+ }
+ if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+
+ if (msgname.v6.sin6_family != AF_INET6) {
+ DUMP_CORE;
+ }
+
+ if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
+ sizeof(msgname.v6.sin6_addr))) {
+ DUMP_CORE;
+ }
+#else
+ if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
+ DUMP_CORE;
+ }
+
+ if (msgname.v4.sin_family != AF_INET) {
+ DUMP_CORE;
+ }
+ if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
+ DUMP_CORE;
+ }
+#endif
+
+ tst_resm(TPASS, "recvmsg SHUTDOWN_COMP notification");
+
+ close(sk2);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_connect.c b/src/func_tests/test_connect.c
new file mode 100644
index 0000000..333c283
--- /dev/null
+++ b/src/func_tests/test_connect.c
@@ -0,0 +1,219 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the one-to-many style connect() in blocking
+ * and non-blocking modes.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 5;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk1, clt_sk2, peeloff_sk;
+ sctp_assoc_t svr_associd1;
+ sockaddr_storage_t svr_loop, clt_loop1, clt_loop2, clt_loop3;
+ struct sctp_assoc_change *sac;
+ struct iovec iov;
+ struct msghdr inmessage;
+ int error;
+ char *big_buffer;
+ int flags;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+ clt_loop1.v4.sin_family = AF_INET;
+ clt_loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop1.v4.sin_port = htons(SCTP_TESTPORT_2);
+ clt_loop2.v4.sin_family = AF_INET;
+ clt_loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop2.v4.sin_port = htons(SCTP_TESTPORT_2+1);
+ clt_loop3.v4.sin_family = AF_INET;
+ clt_loop3.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop3.v4.sin_port = htons(SCTP_TESTPORT_2+2);
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind the client sockets. */
+ clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(clt_sk1, &clt_loop1.sa, sizeof(clt_loop1));
+ clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(clt_sk2, &clt_loop2.sa, sizeof(clt_loop2));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+ test_enable_assoc_change(clt_sk1);
+ test_enable_assoc_change(clt_sk2);
+
+ /* Set clt_sk1 as non-blocking. */
+ flags = fcntl(clt_sk1, F_GETFL, 0);
+ if (flags < 0)
+ tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno));
+ if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0)
+ tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno));
+
+ /* Do a non-blocking connect from clt_sk1 to svr_sk */
+ error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop));
+ /* Non-blocking connect should return immediately with EINPROGRESS. */
+ if ((error != -1) || (EINPROGRESS != errno))
+ tst_brkm(TBROK, tst_exit, "non-blocking connect error: %d"
+ "errno:%d", error, errno);
+
+ tst_resm(TPASS, "non-blocking connect");
+
+ /* Doing a connect on a socket to create an association that is
+ * is already established should return EISCONN.
+ */
+ error = connect(clt_sk1, &svr_loop.sa, sizeof(svr_loop));
+ if ((error != -1) || (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connect on a socket to create an "
+ "assoc that is already established error:%d errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "connect on a socket to create an assoc that is "
+ "already established");
+
+ /* Initialize inmessage for all receives. */
+ memset(&inmessage, 0, sizeof(inmessage));
+ big_buffer = test_malloc(REALLY_BIG);
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = NULL;
+
+ /* Get COMM_UP on clt_sk1 */
+ error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ clt_associd1 = sac->sac_assoc_id;
+#endif
+
+ /* Get COMM_UP on svr_sk */
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd1 = sac->sac_assoc_id;
+
+ /* Do a blocking connect from clt_sk2 to svr_sk.
+ * Blocking connect should block until the association is established
+ * and return success.
+ */
+ test_connect(clt_sk2, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Get COMM_UP on clt_sk2 */
+ error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ clt_associd2 = sac->sac_assoc_id;
+#endif
+
+ /* Get COMM_UP on svr_sk */
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd2 = sac->sac_assoc_id;
+#endif
+
+ tst_resm(TPASS, "blocking connect");
+
+ peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1);
+
+ /* Doing a connect on a peeled off socket should fail. */
+ error = connect(peeloff_sk, &clt_loop3.sa, sizeof(clt_loop3));
+ if ((error != -1) || (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connect on a peeled off socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect on a peeled off socket");
+
+ /* Trying to create an association on a socket that matches an
+ * existing peeled-off association should fail.
+ */
+ error = connect(svr_sk, &clt_loop1.sa, sizeof(clt_loop1));
+ if ((error != -1) || (EADDRNOTAVAIL != errno))
+ tst_brkm(TBROK, tst_exit, "connect to create an assoc that "
+ "matches a peeled off assoc error:%d errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "connect to create an assoc that matches a peeled off "
+ "assoc");
+
+ close(svr_sk);
+ close(clt_sk1);
+ close(clt_sk2);
+ close(peeloff_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_connectx.c b/src/func_tests/test_connectx.c
new file mode 100644
index 0000000..2477241
--- /dev/null
+++ b/src/func_tests/test_connectx.c
@@ -0,0 +1,270 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the one-to-many style sctp_connectx()
+ * in blocking and non-blocking modes.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 9;
+int TST_CNT = 0;
+
+#define NUMADDR 6
+#define SCTP_IP_LOOPBACK_I(I) htonl(0x7f000001 + I)
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk1, clt_sk2, peeloff_sk;
+ sctp_assoc_t associd, svr_associd1, svr_associd2, clt_associd1, clt_associd2;
+ struct iovec iov;
+ struct msghdr inmessage;
+ int error, i;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ int flags;
+ struct sockaddr_in svr_loop[NUMADDR];
+ struct sockaddr_in svr_try[NUMADDR];
+ struct sockaddr_in clt_loop1[NUMADDR];
+ struct sockaddr_in clt_loop2[NUMADDR];
+ struct sockaddr_in clt_loop3[NUMADDR];
+ sockaddr_storage_t svr_test[NUMADDR], clt_test1[NUMADDR], clt_test2[NUMADDR];
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ for (i = 0; i < NUMADDR; i++) {
+ /* Initialize the server and client addresses. */
+ svr_loop[i].sin_family = AF_INET;
+ svr_loop[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+ svr_loop[i].sin_port = htons(SCTP_TESTPORT_1);
+ svr_test[i].v4.sin_family = AF_INET;
+ svr_test[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+ svr_test[i].v4.sin_port = htons(SCTP_TESTPORT_1);
+ svr_try[i].sin_family = AF_INET;
+ if (i < (NUMADDR-1)) {
+ svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i);
+ } else {
+ /* Make last address invalid. */
+ svr_try[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x400);
+ }
+ svr_try[i].sin_port = htons(SCTP_TESTPORT_1);
+ clt_loop1[i].sin_family = AF_INET;
+ clt_loop1[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100);
+ clt_loop1[i].sin_port = htons(SCTP_TESTPORT_2);
+ clt_test1[i].v4.sin_family = AF_INET;
+ clt_test1[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x100);
+ clt_test1[i].v4.sin_port = htons(SCTP_TESTPORT_2);
+ clt_loop2[i].sin_family = AF_INET;
+ clt_loop2[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200);
+ clt_loop2[i].sin_port = htons(SCTP_TESTPORT_2+1);
+ clt_test2[i].v4.sin_family = AF_INET;
+ clt_test2[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x200);
+ clt_test2[i].v4.sin_port = htons(SCTP_TESTPORT_2+1);
+ clt_loop3[i].sin_family = AF_INET;
+ clt_loop3[i].sin_addr.s_addr = SCTP_IP_LOOPBACK_I(i + 0x300);
+ clt_loop3[i].sin_port = htons(SCTP_TESTPORT_2+2);
+ }
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(svr_sk, (struct sockaddr *)&svr_loop[0], sizeof(svr_loop[0]));
+ test_bindx_add(svr_sk, (struct sockaddr *)&svr_loop[1], NUMADDR-1);
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind the client sockets. */
+ clt_sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(clt_sk1, (struct sockaddr *)&clt_loop1[0], sizeof(clt_loop1));
+ test_bindx_add(clt_sk1, (struct sockaddr *)&clt_loop1[1], NUMADDR-1);
+ clt_sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(clt_sk2, (struct sockaddr *)&clt_loop2[0], sizeof(clt_loop2));
+ test_bindx_add(clt_sk2, (struct sockaddr *)&clt_loop2[1], NUMADDR-1);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+ test_enable_assoc_change(clt_sk1);
+ test_enable_assoc_change(clt_sk2);
+
+ /* Set clt_sk1 as non-blocking. */
+ flags = fcntl(clt_sk1, F_GETFL, 0);
+ if (flags < 0)
+ tst_brkm(TBROK, tst_exit, "fcntl F_GETFL: %s", strerror(errno));
+ if (fcntl(clt_sk1, F_SETFL, flags | O_NONBLOCK) < 0)
+ tst_brkm(TBROK, tst_exit, "fcntl F_SETFL: %s", strerror(errno));
+
+ /* Do a non-blocking connectx from clt_sk1 to svr_sk */
+ error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR,
+ &associd);
+ /* Non-blocking connectx should return immediately with EINPROGRESS. */
+ if ((error != -1) || (EINPROGRESS != errno))
+ tst_brkm(TBROK, tst_exit, "non-blocking connectx error: %d"
+ "errno:%d", error, errno);
+
+ tst_resm(TPASS, "non-blocking connectx");
+
+ /* Doing a connectx on a socket to create an association that is
+ * is already established should return EISCONN.
+ */
+ error = sctp_connectx(clt_sk1, (struct sockaddr *)svr_try, NUMADDR,
+ NULL);
+ if ((error != -1) || (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connectx on a socket to create an "
+ "assoc that is already established error:%d errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "connectx on a socket to create an assoc that is "
+ "already established");
+
+ /* Initialize inmessage for all receives. */
+ memset(&inmessage, 0, sizeof(inmessage));
+ big_buffer = test_malloc(REALLY_BIG);
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = NULL;
+
+ /* Get COMM_UP on clt_sk1 */
+ error = test_recvmsg(clt_sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ clt_associd1 = sac->sac_assoc_id;
+
+ if (associd) {
+ if (associd != clt_associd1)
+ tst_brkm(TBROK, tst_exit, "Association id mismatch: "
+ "connectx returned %d, notification returned:%d",
+ associd, clt_associd1);
+ tst_resm(TPASS, "Association id match between sctp_connectx()"
+ " and notification.");
+ }
+
+ /* Get COMM_UP on svr_sk */
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd1 = sac->sac_assoc_id;
+
+ /* Do a blocking connectx from clt_sk2 to svr_sk.
+ * Blocking connectx should block until the association is established
+ * and return success.
+ */
+ test_connectx(clt_sk2, (struct sockaddr *)svr_try, NUMADDR);
+
+ /* Get COMM_UP on clt_sk2 */
+ error = test_recvmsg(clt_sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ clt_associd2 = sac->sac_assoc_id;
+
+ /* Get COMM_UP on svr_sk */
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd2 = sac->sac_assoc_id;
+
+ tst_resm(TPASS, "blocking connectx");
+
+ peeloff_sk = test_sctp_peeloff(svr_sk, svr_associd1);
+
+ /* Doing a connectx on a peeled off socket should fail. */
+ error = sctp_connectx(peeloff_sk, (struct sockaddr *)clt_loop3, NUMADDR,
+ NULL);
+ if ((error != -1) || (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connectx on a peeled off socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connectx on a peeled off socket");
+
+ /* Trying to create an association on a socket that matches an
+ * existing peeled-off association should fail.
+ */
+ error = sctp_connectx(svr_sk, (struct sockaddr *)clt_loop1, NUMADDR,
+ NULL);
+ if ((error != -1) || (EADDRNOTAVAIL != errno))
+ tst_brkm(TBROK, tst_exit, "connectx to create an assoc that "
+ "matches a peeled off assoc error:%d errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "connectx to create an assoc that matches a peeled off "
+ "assoc");
+
+ test_peer_addr(peeloff_sk, svr_associd1, clt_test1, NUMADDR);
+ tst_resm(TPASS, "server association 1 peers ok");
+ test_peer_addr(svr_sk, svr_associd2, clt_test2, NUMADDR);
+ tst_resm(TPASS, "server association 2 peers ok");
+ test_peer_addr(clt_sk1, clt_associd1, svr_test, NUMADDR);
+ tst_resm(TPASS, "client association 1 peers ok");
+ test_peer_addr(clt_sk2, clt_associd2, svr_test, NUMADDR);
+ tst_resm(TPASS, "client association 2 peers ok");
+ close(svr_sk);
+ close(clt_sk1);
+ close(clt_sk2);
+ close(peeloff_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_fragments.c b/src/func_tests/test_fragments.c
new file mode 100644
index 0000000..7feb2b2
--- /dev/null
+++ b/src/func_tests/test_fragments.c
@@ -0,0 +1,297 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Hui Huang <hui.huang@nokia.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a functional test to verify the data fragmentation, reassembly
+ * support and SCTP_DISABLE_FRAGMENTS socket option.
+ * The following tests are done in sequence.
+ * - Verify SCTP_DISABLE_FRAGMENTS socket option by doing a setsockopt()
+ * followed by a getsockopt().
+ * - Verify that a message size exceeding the association fragmentation
+ * point cannot be sent when fragmentation is disabled.
+ * - Send and receive a set of messages that are bigger than the path mtu.
+ * The different message sizes to be tested are specified in the array
+ * msg_sizes[].
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 4;
+int TST_CNT = 0;
+
+int msg_sizes[] = {1353, 2000, 5000, 10000, 20000, 32768};
+
+int
+main(int argc, char *argv[])
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop1;
+ sockaddr_storage_t loop2;
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ int error, bytes_sent;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ char *big_buffer;
+ int msg_len, msg_cnt, i;
+ void *msg_buf;
+ int disable_frag;
+ socklen_t optlen;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ loop1.v6.sin6_family = AF_INET6;
+ loop1.v6.sin6_addr = in6addr_loopback;
+ loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v6.sin6_family = AF_INET6;
+ loop2.v6.sin6_addr = in6addr_loopback;
+ loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+ pf_class = PF_INET;
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk1);
+ test_enable_assoc_change(sk2);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ /* Mark sk2 as being able to accept new associations. */
+ test_listen(sk2, 1);
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &loop2;
+ outmessage.msg_namelen = sizeof(loop2);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ msg_len = 10;
+ msg_buf = test_build_msg(10);
+ outmessage.msg_iov->iov_base = msg_buf;
+ outmessage.msg_iov->iov_len = msg_len;
+ test_sendmsg(sk1, &outmessage, 0, msg_len);
+
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on sk2. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd2 = sac->sac_assoc_id;
+#endif
+ /* Get the communication up message on sk1. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd1 = sac->sac_assoc_id;
+#endif
+ /* Get the first message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, msg_len, MSG_EOR, stream, ppid);
+
+ free(msg_buf);
+
+ /* Disable fragmentation. */
+ disable_frag = 1;
+ test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+ sizeof(disable_frag));
+
+ tst_resm(TPASS, "setsockopt(SCTP_DISABLE_FRAGMENTS)");
+
+ /* Do a getsockopt() and verify that fragmentation is disabled. */
+ disable_frag = 0;
+ optlen = sizeof(disable_frag);
+ error = test_getsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+ &optlen);
+ if ((error != 0) && (disable_frag != 1))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DISABLE_FRAGMENTS) "
+ "error:%d errno:%d disable_frag:%d",
+ error, errno, disable_frag);
+
+ tst_resm(TPASS, "getsockopt(SCTP_DISABLE_FRAGMENTS)");
+
+ /* Try to send a messsage that exceeds association fragmentation point
+ * and verify that it fails.
+ */
+ msg_len = 100000;
+ msg_buf = test_build_msg(msg_len);
+ outmessage.msg_iov->iov_base = msg_buf;
+ outmessage.msg_iov->iov_len = msg_len;
+ error = sendmsg(sk1, &outmessage, 0);
+ if ((error != -1) || (errno != EMSGSIZE))
+ tst_brkm(TBROK, tst_exit, "Send a message that exceeds "
+ "assoc frag point error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "Send a message that exceeds assoc frag point");
+
+ /* Enable Fragmentation. */
+ disable_frag = 0;
+ test_setsockopt(sk1, SCTP_DISABLE_FRAGMENTS, &disable_frag,
+ sizeof(disable_frag));
+
+ msg_cnt = sizeof(msg_sizes) / sizeof(int);
+
+ /* Send and receive the messages of different sizes specified in the
+ * msg_sizes array in a loop.
+ */
+ for (i = 0; i < msg_cnt; i++) {
+
+ msg_len = msg_sizes[i];
+ msg_buf = test_build_msg(msg_len);
+ outmessage.msg_iov->iov_base = msg_buf;
+ outmessage.msg_iov->iov_len = msg_len;
+ bytes_sent = test_sendmsg(sk1, &outmessage, 0, msg_len);
+
+ tst_resm(TINFO, "Sent %d byte message", bytes_sent);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ /* Handle Partial Reads. */
+ if (inmessage.msg_flags & MSG_EOR) {
+ test_check_msg_data(&inmessage, error, bytes_sent,
+ MSG_EOR, stream, ppid);
+ tst_resm(TINFO, "Received %d byte message", error);
+ } else {
+ int remain;
+
+ test_check_msg_data(&inmessage, error, error, 0,
+ stream, ppid);
+ tst_resm(TINFO, "Received %d byte message", error);
+
+ /* Read the remaining message. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ remain = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, remain,
+ bytes_sent - error,
+ MSG_EOR, stream, ppid);
+ tst_resm(TINFO, "Received %d byte message", error);
+ }
+
+ free(msg_buf);
+ }
+
+ tst_resm(TPASS, "Send/Receive fragmented messages");
+
+ /* Shut down the link. */
+ close(sk1);
+
+ /* Get the shutdown complete notification. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ close(sk2);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_getname.c b/src/func_tests/test_getname.c
new file mode 100644
index 0000000..5fc4b3c
--- /dev/null
+++ b/src/func_tests/test_getname.c
@@ -0,0 +1,278 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2004
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify getsockname() and getpeername() interfaces
+ * for single-homed one-to-one style sockets.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 13;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int clt_sk, svr_sk, accept_sk;
+ sockaddr_storage_t svr_loop, accept_loop;
+ sockaddr_storage_t svr_local_addr, svr_peer_addr;
+ sockaddr_storage_t clt_local_addr, clt_peer_addr;
+ socklen_t len;
+ int error;
+ int pf_class;
+ int fd, err_no = 0;
+ char filename[21];
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+#if TEST_V6
+ pf_class = PF_INET6;
+ svr_loop.v6.sin6_family = AF_INET6;
+ svr_loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+ svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+#else
+ pf_class = PF_INET;
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = INADDR_ANY;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+#endif
+
+ /* Create and bind the listening server socket. */
+ svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ memset(&svr_local_addr, 0x00, sizeof(svr_local_addr));
+ len = sizeof(svr_local_addr);
+ /* Verify that getsockname() on an unconnected socket works fine. */
+ error = getsockname(svr_sk, (struct sockaddr *)&svr_local_addr, &len);
+ if (0 != error)
+ tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+
+ tst_resm(TPASS, "getsockname on an unconnected socket");
+
+ memset(&svr_peer_addr, 0x00, sizeof(svr_peer_addr));
+ len = sizeof(svr_peer_addr);
+ /* Verify that getpeername() on an unconnected socket fails. */
+ error = getpeername(svr_sk, (struct sockaddr *)&svr_peer_addr, &len);
+ if ((-1 != error) || (ENOTCONN != errno))
+ tst_brkm(TBROK, tst_exit, "getpeername on an unconnected "
+ "socket error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "getpeername on an unconnected socket");
+
+ /* Mark svr_sk as being able to accept new associations. */
+ test_listen(svr_sk, 5);
+
+ /* Create the client socket. */
+ clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /* Do a blocking connect from clt_sk to svr_sk */
+#if TEST_V6
+ svr_loop.v6.sin6_addr = in6addr_loopback;
+#else
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+#endif
+ test_connect(clt_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ memset(&clt_local_addr, 0x00, sizeof(clt_local_addr));
+ len = sizeof(clt_local_addr);
+ /* Get the client's local address. */
+ error = getsockname(clt_sk, (struct sockaddr *)&clt_local_addr, &len);
+ if (0 != error)
+ tst_brkm(TBROK, tst_exit, "getsockname on a connected client "
+ "socket: %s", strerror(errno));
+
+ tst_resm(TPASS, "getsockname on a connected client socket");
+
+ memset(&clt_peer_addr, 0x00, sizeof(clt_peer_addr));
+ len = sizeof(clt_peer_addr);
+ /* Get the client's peer address. */
+ error = getpeername(clt_sk, (struct sockaddr *)&clt_peer_addr, &len);
+ if (0 != error)
+ tst_brkm(TBROK, tst_exit, "getpeername on a connected client "
+ "socket: %s", strerror(errno));
+
+ tst_resm(TPASS, "getpeername on a connected client socket");
+
+ /* Extract the association on the listening socket as a new socket. */
+ len = sizeof(accept_loop);
+ accept_sk = test_accept(svr_sk, &accept_loop.sa, &len);
+
+ memset(&svr_local_addr, 0x00, sizeof(svr_local_addr));
+ len = sizeof(svr_local_addr);
+ /* Get the server's local address. */
+ error = getsockname(accept_sk, (struct sockaddr *)&svr_local_addr,
+ &len);
+ if (0 != error)
+ tst_brkm(TBROK, tst_exit, "getsockname on a connected server "
+ "socket: %s", strerror(errno));
+
+ tst_resm(TPASS, "getsockname on a connected server socket");
+
+ memset(&svr_peer_addr, 0x00, sizeof(svr_peer_addr));
+ len = sizeof(svr_peer_addr);
+ /* Get the server's peer address. */
+ error = getpeername(accept_sk, (struct sockaddr *)&svr_peer_addr,
+ &len);
+ if (0 != error)
+ tst_brkm(TBROK, tst_exit, "getpeername on a connected server "
+ "socket: %s", strerror(errno));
+
+ tst_resm(TPASS, "getpeername on a connected server socket");
+
+ if (svr_local_addr.v4.sin_port != clt_peer_addr.v4.sin_port)
+ tst_brkm(TBROK, tst_exit, "Server's local port(%d) doesn't "
+ "match Client's peer port(%d)\n",
+ svr_local_addr.v4.sin_port, clt_peer_addr.v4.sin_port);
+
+ if (svr_peer_addr.v4.sin_port != clt_local_addr.v4.sin_port)
+ tst_brkm(TBROK, tst_exit, "Server's peer port(%d) doesn't "
+ "match Client's local port(%d)\n",
+ svr_peer_addr.v4.sin_port, clt_local_addr.v4.sin_port);
+#if TEST_V6
+ if (memcmp(&svr_local_addr, &clt_peer_addr, len) != 0)
+ tst_brkm(TBROK, tst_exit, "Server's local address and client's "
+ "peer addresses do not match\n");
+
+ if (memcmp(&svr_peer_addr, &clt_local_addr, len) != 0)
+ tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
+ "local addresses do not match\n");
+#else
+ if (svr_local_addr.v4.sin_addr.s_addr !=
+ clt_peer_addr.v4.sin_addr.s_addr)
+ tst_brkm(TBROK, tst_exit, "Server's local address and client's "
+ "peer addresses do not match\n");
+ if (svr_peer_addr.v4.sin_addr.s_addr !=
+ clt_local_addr.v4.sin_addr.s_addr)
+ tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
+ "local addresses do not match\n");
+#endif
+ tst_resm(TPASS, "getsockname/getpeername server/client match");
+
+ memset(&clt_local_addr, 0x00, sizeof(clt_local_addr));
+ len = sizeof(clt_local_addr);
+ /*getsockname(): Bad socket descriptor, EBADF expected error*/
+ error = getsockname(-1, (struct sockaddr *)&clt_local_addr, &len);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "getsockname on a bad socket "
+ "descriptor. error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockname on a bad socket descriptor - EBADF");
+
+ /*getsockname(): Invalid socket, ENOTSOCK expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = getsockname(fd, (struct sockaddr *)&clt_local_addr, &len);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "getsockname on an invalid socket "
+ "error:%d errno:%d", error, err_no);
+
+ tst_resm(TPASS, "getsockname on an invalid socket - ENOTSOCK");
+
+ /*getsockname(): Invalid structure, EFAULT expected error*/
+ error = getsockname(clt_sk, (struct sockaddr *)-1, &len);
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "getsockname with invalid buffer "
+ "error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockname with invalid buffer - EFAULT");
+
+ memset(&clt_peer_addr, 0x00, sizeof(clt_peer_addr));
+ len = sizeof(clt_peer_addr);
+ /*getpeername(): Bad socket descriptor, EBADF expected error*/
+ error = getpeername(-1, (struct sockaddr *)&clt_local_addr, &len);
+ if (error != -1 || errno != EBADF)
+ tst_brkm(TBROK, tst_exit, "getpeername on a bad socket "
+ "descriptor. error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getpeername on a bad socket descriptor - EBADF");
+
+ /*getpeername(): Invalid socket, ENOTSOCK expected error*/
+ strcpy(filename, "/tmp/sctptest.XXXXXX");
+ fd = mkstemp(filename);
+ if (fd == -1)
+ tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
+ filename, strerror(errno));
+ error = getpeername(fd, (struct sockaddr *)&clt_local_addr, &len);
+ if (error == -1)
+ err_no = errno;
+ close(fd);
+ unlink(filename);
+ if (error != -1 || err_no != ENOTSOCK)
+ tst_brkm(TBROK, tst_exit, "getpeername on an invalid socket "
+ "error:%d errno:%d", error, err_no);
+
+ tst_resm(TPASS, "getpeername on an invalid socket - ENOTSOCK");
+
+ /*getpeername(): Invalid structure, EFAULT expected error*/
+ error = getpeername(clt_sk, (struct sockaddr *)-1, &len);
+ if (error != -1 || errno != EFAULT)
+ tst_brkm(TBROK, tst_exit, "getpeername with invalid buffer "
+ "error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getpeername with invalid buffer - EFAULT");
+
+ close(clt_sk);
+ close(svr_sk);
+ close(accept_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_inaddr_any.c b/src/func_tests/test_inaddr_any.c
new file mode 100644
index 0000000..722a702
--- /dev/null
+++ b/src/func_tests/test_inaddr_any.c
@@ -0,0 +1,251 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ */
+
+/* This is a functional test to verify binding a socket with INADDRY_ANY
+ * address and send messages.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 2;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop;
+ sockaddr_storage_t anyaddr;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ struct iovec iov;
+ struct msghdr inmessage;
+ char *message = "hello, world!\n";
+ char *telephone = "Watson, come here! I need you!\n";
+ char *telephone_resp = "I already brought your coffee...\n";
+ int error;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ socklen_t namelen;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ loop.v6.sin6_family = AF_INET6;
+ loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_LOOPBACK_INIT;
+ loop.v6.sin6_port = 0;
+
+ anyaddr.v6.sin6_family = AF_INET6;
+ anyaddr.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
+ anyaddr.v6.sin6_port = 0;
+#else
+ pf_class = PF_INET;
+
+ loop.v4.sin_family = AF_INET;
+ loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop.v4.sin_port = 0;
+
+ anyaddr.v4.sin_family = AF_INET;
+ anyaddr.v4.sin_addr.s_addr = INADDR_ANY;
+ anyaddr.v4.sin_port = 0;
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(sk1);
+ test_enable_assoc_change(sk2);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop.sa, sizeof(loop));
+ test_bind(sk2, &anyaddr.sa, sizeof(anyaddr));
+
+ tst_resm(TPASS, "bind INADDR_ANY address");
+
+ /* Mark sk2 as being able to accept new associations */
+ test_listen(sk2, 1);
+
+ /* Now use getsockaname() to retrieve the ephmeral ports. */
+ namelen = sizeof(loop);
+ error = getsockname(sk1, &loop.sa, &namelen);
+ if (error != 0)
+ tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+
+ namelen = sizeof(anyaddr);
+ error = getsockname(sk2, &anyaddr.sa, &namelen);
+ if (error != 0)
+ tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
+
+#if TEST_V6
+ loop.v6.sin6_port = anyaddr.v6.sin6_port;
+#else
+ loop.v4.sin_port = anyaddr.v4.sin_port;
+#endif
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &loop;
+ outmessage.msg_namelen = sizeof(loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = test_malloc(REALLY_BIG);
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on sk2. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Get the communication up message on sk1. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Get the first message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+
+ /* Send 2 messages. */
+ outmessage.msg_name = &loop;
+ outmessage.msg_namelen = sizeof(loop);
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid++;
+ stream++;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = telephone;
+ outmessage.msg_iov->iov_len = strlen(telephone) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1);
+
+ outmessage.msg_iov->iov_base = telephone_resp;
+ outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1);
+
+ /* Get those two messages. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(telephone) + 1,
+ MSG_EOR, stream, ppid);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1,
+ MSG_EOR, stream, ppid);
+
+ /* Shut down the link. */
+ close(sk1);
+
+ /* Get the shutdown complete notification. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ close(sk2);
+
+ tst_resm(TPASS, "send msgs from a socket with INADDR_ANY bind address");
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_peeloff.c b/src/func_tests/test_peeloff.c
new file mode 100644
index 0000000..8fb7a00
--- /dev/null
+++ b/src/func_tests/test_peeloff.c
@@ -0,0 +1,299 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a Functional test to verify the new SCTP interface sctp_peeloff()
+ * that can be used to branch off an association into a separate socket.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk[MAX_CLIENTS], peeloff_sk[MAX_CLIENTS];
+ sctp_assoc_t svr_associd[MAX_CLIENTS];
+ sockaddr_storage_t svr_loop, clt_loop[MAX_CLIENTS];
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ int error;
+ uint32_t ppid;
+ uint32_t stream;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ int i;
+ char *message = "hello, world!\n";
+ int pf_class;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+#if TEST_V6
+ pf_class = PF_INET6;
+ svr_loop.v6.sin6_family = AF_INET6;
+ svr_loop.v6.sin6_addr = in6addr_loopback;
+ svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+#else
+ pf_class = PF_INET;
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+#endif
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind all the client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_sk[i] = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+#if TEST_V6
+ clt_loop[i].v6.sin6_family = AF_INET6;
+ clt_loop[i].v6.sin6_addr = in6addr_loopback;
+ clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+#else
+ clt_loop[i].v4.sin_family = AF_INET;
+ clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+#endif
+ test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+
+ test_enable_assoc_change(clt_sk[i]);
+ }
+
+ /* Send the first message from all the clients to the server. This
+ * will create the associations.
+ */
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ for (i = 0; i < MAX_CLIENTS; i++)
+ test_sendmsg(clt_sk[i], &outmessage, 0,
+ strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on all client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ clt_associd[i] = sac->sac_assoc_id;
+#endif
+ }
+
+ /* Get the communication up message and the data message on the
+ * server sockets for all the clients.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ svr_associd[i] = sac->sac_assoc_id;
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+ }
+
+ /* Branch off all the associations on the server socket to separate
+ * individual sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ peeloff_sk[i] = test_sctp_peeloff(svr_sk, svr_associd[i]);
+
+ tst_resm(TPASS, "sctp_peeloff");
+
+ errno = 0;
+ /* Verify that a peeled off socket is not allowed to do a listen(). */
+ error = listen(peeloff_sk[0], 1);
+ if (error != -1)
+ tst_brkm(TBROK, tst_exit, "listen on a peeled off socket "
+ "error: %d, errno: %d", error, errno);
+
+ tst_resm(TPASS, "listen on a peeled off socket");
+
+ errno = 0;
+ /* Verify that an association cannot be branched off an already
+ * peeled-off socket.
+ */
+ if ((-1 != sctp_peeloff(peeloff_sk[0], svr_associd[0])) ||
+ (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "sctp_peeloff on a peeled off "
+ "socket error:%d, errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "sctp_peeloff on a peeled off socket");
+
+ /* Send a message from all the client sockets to the server socket. */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ test_sendmsg(clt_sk[i], &outmessage, 0, strlen(message)+1);
+
+ /* Receive the sent messages on the peeled off server sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(peeloff_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+ }
+
+ tst_resm(TPASS, "Receive msgs on peeled off sockets");
+
+ /* Send a message from all the peeled off server sockets to the client
+ * sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ outmessage.msg_name = &clt_loop[i];
+ outmessage.msg_namelen = sizeof(clt_loop[i]);
+ test_sendmsg(peeloff_sk[i], &outmessage, 0, strlen(message)+1);
+ }
+
+ /* Receive the messages sent from the peeled of server sockets on
+ * the client sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+ }
+
+ tst_resm(TPASS, "Send msgs on peeled off sockets");
+
+ errno = 0;
+ /* Verify that a peeled-off socket cannot initialize a new
+ * association by trying to send a message to a client that is not
+ * associated with the peeled-off socket.
+ * The message is sent to the client that is associated with the
+ * socket.
+ */
+ outmessage.msg_name = &clt_loop[1];
+ outmessage.msg_namelen = sizeof(clt_loop[1]);
+ test_sendmsg(peeloff_sk[0], &outmessage, 0, strlen(message)+1);
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+
+ tst_resm(TPASS, "peeled off socket cannot initialize a new assoc");
+
+ close(svr_sk);
+
+ /* Close all the peeled off server sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ close(peeloff_sk[i]);
+
+ /* Get the shutdown complete notification from all the client
+ * sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk[i], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE,
+ SCTP_SHUTDOWN_COMP);
+
+ close(clt_sk[i]);
+ }
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_recvmsg.c b/src/func_tests/test_recvmsg.c
new file mode 100644
index 0000000..b16cceb
--- /dev/null
+++ b/src/func_tests/test_recvmsg.c
@@ -0,0 +1,160 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2002, 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * This file is part of the SCTP kernel Implementation
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+/* This is a kernel test to verify
+ * 1. MSG_EOR flag is set correctly when a single message is read using multiple
+ * recvmsg() calls.
+ * 2. MSG_PEEK support.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 2;
+int TST_CNT = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int svr_sk, clt_sk;
+ struct sockaddr_in svr_loop, clt_loop;
+ struct iovec iov, out_iov;
+ struct msghdr inmessage, outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ int error, msglen, i;
+ char *big_buffer;
+ void *msg_buf;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+ svr_loop.sin_family = AF_INET;
+ svr_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.sin_port = htons(SCTP_TESTPORT_1);
+ clt_loop.sin_family = AF_INET;
+ clt_loop.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop.sin_port = htons(SCTP_TESTPORT_2);
+
+ /* Create and bind the server socket. */
+ svr_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(svr_sk, (struct sockaddr *)&svr_loop, sizeof(svr_loop));
+
+ /* Mark server socket as being able to accept new associations. */
+ test_listen(svr_sk, 1);
+
+ /* Create and bind the client sockets. */
+ clt_sk = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+ test_bind(clt_sk, (struct sockaddr *)&clt_loop, sizeof(clt_loop));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(svr_sk);
+ test_enable_assoc_change(clt_sk);
+
+ /* Send a message. This will create the association. */
+ memset(&outmessage, 0, sizeof(outmessage));
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ msg_buf = test_build_msg(30000);
+ outmessage.msg_iov->iov_base = msg_buf;
+ outmessage.msg_iov->iov_len = 30000;
+ test_sendmsg(clt_sk, &outmessage, 0, 30000);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = 2000;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Receive COMM_UP on clt_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(clt_sk, &inmessage, 0);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Receive COMM_UP on svr_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ /* Read the 30000 byte message using multiple recvmsg() calls in a
+ * loop with 2000 bytes per read.
+ */
+ for (i = 0, msglen = 30000; i < 15; i++, msglen-=2000) {
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_PEEK);
+ test_check_msg_data(&inmessage, error, msglen,
+ MSG_EOR, 0, 0);
+
+ iov.iov_len = 2000;
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, 2000,
+ ((i==14)?MSG_EOR:0), 0, 0);
+ }
+
+ tst_resm(TPASS, "recvmsg with MSG_PEEK flag");
+ tst_resm(TPASS, "MSG_EOR in msg_flags set correctly");
+
+ close(svr_sk);
+ close(clt_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_sctp_sendrecvmsg.c b/src/func_tests/test_sctp_sendrecvmsg.c
new file mode 100644
index 0000000..ceccd5a
--- /dev/null
+++ b/src/func_tests/test_sctp_sendrecvmsg.c
@@ -0,0 +1,370 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2003 Intel Corp.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * To compile the v6 version, set the symbol TEST_V6 to 1.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a basic functional test for the SCTP new library APIs
+ * sctp_sendmsg() and sctp_recvmsg(). test_timetolive.c is rewritten using
+ * these new APIs.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT = 0;
+
+/* RCVBUF value, and indirectly RWND*2 */
+#define SMALL_RCVBUF 3000
+#define SMALL_MAXSEG 500
+/* This is extra data length to ensure rwnd closes */
+#define RWND_SLOP 100
+static char *fillmsg = NULL;
+static char *ttlmsg = "This should time out!\n";
+static char *nottlmsg = "This should NOT time out!\n";
+static char ttlfrag[SMALL_MAXSEG*3] = {0};
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop1;
+ sockaddr_storage_t loop2;
+ sockaddr_storage_t msgname;
+ int error;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ struct sctp_event_subscribe subscribe;
+ char *big_buffer;
+ int offset, msg_flags;
+ socklen_t msgname_len;
+ size_t buflen;
+ struct sctp_send_failed *ssf;
+ struct sctp_sndrcvinfo sinfo;
+ struct sctp_sndrcvinfo snd_sinfo;
+ sctp_assoc_t associd1;
+ socklen_t len, oldlen;
+ struct sctp_status gstatus;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ loop1.v6.sin6_family = AF_INET6;
+ loop1.v6.sin6_addr = in6addr_loopback;
+ loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v6.sin6_family = AF_INET6;
+ loop2.v6.sin6_addr = in6addr_loopback;
+ loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+ pf_class = PF_INET;
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Set the MAXSEG to something smallish. */
+ {
+ int val = SMALL_MAXSEG;
+ test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val));
+ }
+
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ subscribe.sctp_send_failure_event = 1;
+ test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+ test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ /*
+ * Set the RWND small so we can fill it up easily.
+ */
+ len = sizeof(int);
+ error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, &len);
+
+ if (error)
+ tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s",
+ strerror(errno));
+
+ len = SMALL_RCVBUF; /* Really becomes 2xlen when set. */
+
+ error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
+ if (error)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s",
+ strerror(errno));
+
+ /* Mark sk2 as being able to accept new associations. */
+ test_listen(sk2, 1);
+
+ /* Send the first message. This will create the association. */
+ ppid = rand();
+ stream = 1;
+ test_sctp_sendmsg(sk1, message, strlen(message) + 1,
+ (struct sockaddr *)&loop2, sizeof(loop2),
+ ppid, 0, stream, 0, 0);
+
+ tst_resm(TPASS, "sctp_sendmsg");
+
+ /* Get the communication up message on sk2. */
+ buflen = REALLY_BIG;
+ big_buffer = test_malloc(buflen);
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+#if 0
+ associd2 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id;
+#endif
+ test_check_buf_notification(big_buffer, error, msg_flags,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+
+ /* Get the communication up message on sk1. */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ associd1 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id;
+ test_check_buf_notification(big_buffer, error, msg_flags,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+
+ tst_resm(TPASS, "sctp_recvmsg SCTP_COMM_UP notification");
+
+ /* Get the first message which was sent. */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+ strlen(message) + 1, MSG_EOR, stream, ppid);
+
+ tst_resm(TPASS, "sctp_recvmsg data");
+
+ /* Figure out how big to make our fillmsg */
+ len = sizeof(struct sctp_status);
+ memset(&gstatus,0,sizeof(struct sctp_status));
+ gstatus.sstat_assoc_id = associd1;
+ error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+
+ if (error)
+ tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s",
+ strerror(errno));
+ tst_resm(TINFO, "creating a fillmsg of size %d",
+ gstatus.sstat_rwnd+RWND_SLOP);
+ fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP);
+
+ /* Send a fillmsg */
+ memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP);
+ fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0';
+ ppid++;
+ stream++;
+ test_sctp_sendmsg(sk1, fillmsg, gstatus.sstat_rwnd+RWND_SLOP,
+ (struct sockaddr *)&loop2, sizeof(loop2),
+ ppid, 0, stream, 0, 0);
+
+ /* Now send a message that will timeout. */
+ test_sctp_sendmsg(sk1, ttlmsg, strlen(ttlmsg) + 1,
+ (struct sockaddr *)&loop2, sizeof(loop2),
+ ppid, 0, stream, 2000, 0);
+
+ tst_resm(TPASS, "sctp_sendmsg with ttl");
+
+ /* Next send a message that won't time out. */
+ test_sctp_sendmsg(sk1, nottlmsg, strlen(nottlmsg) + 1,
+ (struct sockaddr *)&loop2, sizeof(loop2),
+ ppid, 0, stream, 0, 0);
+
+ tst_resm(TPASS, "sctp_sendmsg with zero ttl");
+
+ /* And finally a fragmented message that will time out. */
+ memset(ttlfrag, 48, sizeof(ttlfrag)); /* 48 is the ascii of '0' */
+ ttlfrag[sizeof(ttlfrag)-1] = '\0';
+ test_sctp_sendmsg(sk1, ttlfrag, sizeof(ttlfrag),
+ (struct sockaddr *)&loop2, sizeof(loop2),
+ ppid, 0, stream, 2000, 0);
+
+ tst_resm(TPASS, "sctp_sendmsg fragmented msg with ttl");
+
+ /* Sleep waiting for the message to time out. */
+ tst_resm(TINFO, "** SLEEPING for 3 seconds **");
+ sleep(3);
+
+ /* Get the fillmsg. */
+ do {
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ } while (!(msg_flags & MSG_EOR));
+
+ /* Get the message that did NOT time out. */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+ strlen(nottlmsg) + 1, MSG_EOR, stream, ppid);
+ if (0 != strncmp(big_buffer, nottlmsg, strlen(nottlmsg)))
+ tst_brkm(TBROK, tst_exit, "sctp_recvmsg: Wrong Message !!!");
+
+ tst_resm(TPASS, "sctp_recvmsg msg with zero ttl");
+
+ /* Get the SEND_FAILED notification for the message that DID
+ * time out.
+ */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_notification(big_buffer, error, msg_flags,
+ sizeof(struct sctp_send_failed) +
+ strlen(ttlmsg) + 1,
+ SCTP_SEND_FAILED, 0);
+ ssf = (struct sctp_send_failed *)big_buffer;
+ if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1))
+ tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+
+ tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for message with ttl");
+
+ offset = 0;
+
+ /* Get the SEND_FAILED notifications for the fragmented message that
+ * timed out.
+ */
+ do {
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk1, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_notification(big_buffer, error, msg_flags,
+ sizeof(struct sctp_send_failed) +
+ SMALL_MAXSEG,
+ SCTP_SEND_FAILED, 0);
+ ssf = (struct sctp_send_failed *)big_buffer;
+ if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data,
+ SMALL_MAXSEG))
+ tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+ offset += SMALL_MAXSEG;
+ } while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST FRAG */
+
+ tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for fragmented message with "
+ "ttl");
+
+ snd_sinfo.sinfo_ppid = rand();
+ snd_sinfo.sinfo_flags = 0;
+ snd_sinfo.sinfo_stream = 2;
+ snd_sinfo.sinfo_timetolive = 0;
+ snd_sinfo.sinfo_assoc_id = associd1;
+ test_sctp_send(sk1, message, strlen(message) + 1, &snd_sinfo,
+ MSG_NOSIGNAL);
+
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_data(big_buffer, error, msg_flags, &sinfo,
+ strlen(message) + 1, MSG_EOR, snd_sinfo.sinfo_stream,
+ snd_sinfo.sinfo_ppid);
+
+ tst_resm(TPASS, "sctp_send");
+
+ /* Shut down the link. */
+ close(sk1);
+
+ /* Get the shutdown complete notification. */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ error = test_sctp_recvmsg(sk2, big_buffer, buflen,
+ (struct sockaddr *)&msgname, &msgname_len,
+ &sinfo, &msg_flags);
+ test_check_buf_notification(big_buffer, error, msg_flags,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ close(sk2);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_sctp_sendvrecvv.c b/src/func_tests/test_sctp_sendvrecvv.c
new file mode 100644
index 0000000..4991e79
--- /dev/null
+++ b/src/func_tests/test_sctp_sendvrecvv.c
@@ -0,0 +1,270 @@
+/* SCTP kernel Implementation
+ * (C) Copyright REDHAT Corp. 2018
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * To compile the v6 version, set the symbol TEST_V6 to 1.
+ *
+ * Written or modified by:
+ * Xin Long <lucien.xin@gmail.com>
+ */
+
+/* This is a basic functional test for the SCTP new library APIs
+ * sctp_sendv() and sctp_recvv().
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 10;
+int TST_CNT;
+
+/* RCVBUF value, and indirectly RWND*2 */
+#define SMALL_RCVBUF 3000
+#define SMALL_MAXSEG 500
+/* This is extra data length to ensure rwnd closes */
+#define RWND_SLOP 100
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+ sockaddr_storage_t loop1, loop2, msgname;
+ int sk1, sk2, error, buflen, i, addrcnt;
+ socklen_t msgname_len, rn_len;
+ struct sctp_authinfo authinfo;
+ struct sctp_sndinfo sndinfo;
+ struct sockaddr *addr_list;
+ struct sctp_sendv_spa spa;
+ uint32_t infotype, stream;
+ struct iovec iov, iovx[3];
+ struct sctp_prinfo prinfo;
+ struct sctp_recvv_rn rn;
+ int pf_class, msg_flags;
+ socklen_t val = 1;
+ char addr_str[64];
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ struct sockaddr_in6 *v6addrs;
+
+ pf_class = PF_INET6;
+
+ loop1.v6.sin6_family = AF_INET6;
+ loop1.v6.sin6_addr = in6addr_loopback;
+ loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v6.sin6_family = AF_INET6;
+ loop2.v6.sin6_addr = in6addr_loopback;
+ loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+
+ addrcnt = 5;
+ v6addrs = test_malloc(sizeof(*v6addrs) * addrcnt);
+ v6addrs[0].sin6_family = PF_INET6;
+ v6addrs[0].sin6_addr = in6addr_loopback;
+ v6addrs[0].sin6_port = htons(SCTP_TESTPORT_2);
+ for (i = 1; i < addrcnt; i++) {
+ sprintf(addr_str, "2020::%d", i);
+ v6addrs[i].sin6_family = PF_INET6;
+ inet_pton(PF_INET6, addr_str, &v6addrs[i].sin6_addr);
+ }
+ addr_list = (struct sockaddr *)v6addrs;
+#else
+ struct sockaddr_in *v4addrs;
+
+ pf_class = PF_INET;
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+
+ addrcnt = 5;
+ v4addrs = test_malloc(sizeof(*v4addrs) * addrcnt);
+ v4addrs[0].sin_family = PF_INET;
+ v4addrs[0].sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ v4addrs[0].sin_port = htons(SCTP_TESTPORT_2);
+ for (i = 1; i < addrcnt; i++) {
+ sprintf(addr_str, "172.16.1.%d", i);
+ v4addrs[i].sin_family = PF_INET;
+ v4addrs[i].sin_addr.s_addr = inet_addr(addr_str);
+ }
+ addr_list = (struct sockaddr *)v4addrs;
+#endif /* TEST_V6 */
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ /* Mark sk2 as being able to accept new associations. */
+ test_listen(sk2, 1);
+
+
+ /* Testing for sctp_sendv */
+ iov.iov_base = message;
+ iov.iov_len = strlen(message) + 1;
+ test_sctp_sendv(sk1, &iov, 1, addr_list, addrcnt, NULL, 0, 0, 0);
+ tst_resm(TPASS, "sctp_sendv addr info");
+
+ stream = 1;
+ memset(&sndinfo, 0, sizeof(sndinfo));
+ sndinfo.snd_flags = SCTP_UNORDERED;
+ sndinfo.snd_sid = stream;
+ test_sctp_sendv(sk1, &iov, 1, addr_list, addrcnt, &sndinfo,
+ sizeof(sndinfo), SCTP_SENDV_SNDINFO, 0);
+ tst_resm(TPASS, "sctp_sendv sndinfo with stream %d", stream);
+
+ iovx[0].iov_base = message;
+ iovx[0].iov_len = strlen(message) + 1;
+ iovx[1].iov_base = message;
+ iovx[1].iov_len = strlen(message) + 1;
+ iovx[2].iov_base = message;
+ iovx[2].iov_len = strlen(message) + 1;
+
+ stream = 2;
+ sndinfo.snd_sid = stream;
+ test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &sndinfo,
+ sizeof(sndinfo), SCTP_SENDV_SNDINFO, 0);
+ tst_resm(TPASS, "sctp_sendv sndinfo with stream %d", stream);
+
+ prinfo.pr_policy = SCTP_PR_SCTP_RTX;
+ prinfo.pr_value = 10;
+ test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &prinfo,
+ sizeof(prinfo), SCTP_SENDV_PRINFO, 0);
+ tst_resm(TPASS, "sctp_sendv prinfo");
+
+ authinfo.auth_keynumber = 0;
+ test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &authinfo,
+ sizeof(authinfo), SCTP_SENDV_AUTHINFO, 0);
+ tst_resm(TPASS, "sctp_sendv authinfo");
+
+
+ spa.sendv_sndinfo = sndinfo;
+ spa.sendv_prinfo = prinfo;
+ spa.sendv_authinfo = authinfo;
+
+ stream = 3;
+ spa.sendv_sndinfo.snd_sid = stream;
+ spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID;
+ test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &spa,
+ sizeof(spa), SCTP_SENDV_SPA, 0);
+ tst_resm(TPASS, "sctp_sendv spa with stream %d", stream);
+
+ stream = 4;
+ spa.sendv_sndinfo.snd_sid = stream;
+ spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID |
+ SCTP_SEND_AUTHINFO_VALID;
+ test_sctp_sendv(sk1, iovx, 3, addr_list, addrcnt, &spa,
+ sizeof(spa), SCTP_SENDV_SPA, 0);
+ tst_resm(TPASS, "sctp_sendv spa with stream %d", stream);
+
+ /* Testing for sctp_recvv */
+ buflen = REALLY_BIG;
+ msgname_len = sizeof(msgname);
+ msg_flags = 0;
+ iov.iov_base = test_malloc(buflen);
+ iov.iov_len = buflen;
+ rn_len = sizeof(rn);
+
+ error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+ &msgname_len, &rn, &rn_len, &infotype,
+ &msg_flags);
+ if (infotype != SCTP_RECVV_NOINFO)
+ tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+ infotype, SCTP_RECVV_NOINFO);
+ tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NOINFO");
+
+ error = setsockopt(sk2, SOL_SCTP, SCTP_RECVRCVINFO,
+ &val, sizeof(val));
+ if (error)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_RECVRCVINFO): %s",
+ strerror(errno));
+
+ error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+ &msgname_len, &rn, &rn_len, &infotype,
+ &msg_flags);
+ if (infotype != SCTP_RECVV_RCVINFO ||
+ rn.recvv_rcvinfo.rcv_sid != 1)
+ tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+ infotype, SCTP_RECVV_NOINFO);
+ tst_resm(TPASS, "sctp_recvv SCTP_RECVV_RCVINFO");
+
+ error = setsockopt(sk2, SOL_SCTP, SCTP_RECVNXTINFO,
+ &val, sizeof(val));
+ if (error)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_RECVNXTINFO): %s",
+ strerror(errno));
+
+ rn_len = 1;
+ error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+ &msgname_len, &rn, &rn_len, &infotype,
+ &msg_flags);
+ if (infotype != SCTP_RECVV_NOINFO)
+ tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+ infotype, SCTP_RECVV_NOINFO);
+ tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NOINFO due to small size");
+
+ rn_len = sizeof(struct sctp_nxtinfo);
+ error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+ &msgname_len, &rn, &rn_len, &infotype,
+ &msg_flags);
+ if (infotype != SCTP_RECVV_NXTINFO)
+ tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+ infotype, SCTP_RECVV_NXTINFO);
+ tst_resm(TPASS, "sctp_recvv SCTP_RECVV_NXTINFO due to small size");
+
+ rn_len = sizeof(rn);
+ error = test_sctp_recvv(sk2, &iov, 1, (struct sockaddr *)&msgname,
+ &msgname_len, &rn, &rn_len, &infotype,
+ &msg_flags);
+ if (infotype != SCTP_RECVV_RN ||
+ rn.recvv_rcvinfo.rcv_sid != 0 || rn.recvv_nxtinfo.nxt_sid != 3)
+ tst_brkm(TBROK, tst_exit, "sctp_recvv infotype %d != %d",
+ infotype, SCTP_RECVV_RN);
+ tst_resm(TPASS, "sctp_recvv SCTP_RECVV_RN");
+
+ close(sk1);
+ close(sk2);
+
+ return 0;
+}
diff --git a/src/func_tests/test_sockopt.c b/src/func_tests/test_sockopt.c
new file mode 100644
index 0000000..2bd1097
--- /dev/null
+++ b/src/func_tests/test_sockopt.c
@@ -0,0 +1,1147 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Hui Huang <hui.huang@nokia.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <samudrala@us.ibm.com>
+ */
+
+/* This is a functional test to verify the various SCTP level socket
+ * options that can be used to get information about existing SCTP
+ * associations and to configure certain parameters.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 29;
+int TST_CNT = 0;
+
+int
+main(void)
+{
+ int udp_svr_sk, udp_clt_sk, tcp_svr_sk, tcp_clt_sk;
+ int accept_sk, peeloff_sk;
+ sockaddr_storage_t udp_svr_loop, udp_clt_loop;
+ sockaddr_storage_t tcp_svr_loop, tcp_clt_loop;
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ char *message = "hello, world!\n";
+ int error;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ sctp_assoc_t udp_svr_associd, udp_clt_associd;
+ struct sctp_assoc_change *sac;
+ char *big_buffer;
+ struct sctp_event_subscribe subscribe;
+ struct sctp_initmsg initmsg;
+ struct sctp_paddrparams paddrparams;
+ struct sctp_sndrcvinfo set_udp_sk_dflt_param, get_udp_sk_dflt_param;
+ struct sctp_sndrcvinfo set_tcp_sk_dflt_param, get_tcp_sk_dflt_param;
+ struct sctp_sndrcvinfo set_udp_assoc_dflt_param;
+ struct sctp_sndrcvinfo get_udp_assoc_dflt_param;
+ struct sctp_sndrcvinfo set_tcp_assoc_dflt_param;
+ struct sctp_sndrcvinfo get_tcp_assoc_dflt_param;
+ struct sctp_sndrcvinfo get_peeloff_assoc_dflt_param;
+ struct sctp_sndrcvinfo get_accept_assoc_dflt_param;
+ struct sctp_paddrinfo pinfo;
+ int dflt_pathmaxrxt;
+ socklen_t optlen, addrlen;
+ struct sctp_status status;
+ struct sctp_assoc_value value;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ udp_svr_loop.v6.sin6_family = AF_INET6;
+ udp_svr_loop.v6.sin6_addr = in6addr_loopback;
+ udp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ udp_clt_loop.v6.sin6_family = AF_INET6;
+ udp_clt_loop.v6.sin6_addr = in6addr_loopback;
+ udp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+1);
+
+ tcp_svr_loop.v6.sin6_family = AF_INET6;
+ tcp_svr_loop.v6.sin6_addr = in6addr_loopback;
+ tcp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+2);
+
+ tcp_clt_loop.v6.sin6_family = AF_INET6;
+ tcp_clt_loop.v6.sin6_addr = in6addr_loopback;
+ tcp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+3);
+#else
+ pf_class = PF_INET;
+
+ udp_svr_loop.v4.sin_family = AF_INET;
+ udp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ udp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ udp_clt_loop.v4.sin_family = AF_INET;
+ udp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ udp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_1+1);
+
+ tcp_svr_loop.v4.sin_family = AF_INET;
+ tcp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ tcp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1+2);
+
+ tcp_clt_loop.v4.sin_family = AF_INET;
+ tcp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ tcp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_2+3);
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(udp_svr_sk);
+ test_enable_assoc_change(udp_clt_sk);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+ test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+ /* Mark udp_svr_sk as being able to accept new associations. */
+ test_listen(udp_svr_sk, 1);
+
+ /* TEST #1: SCTP_STATUS socket option. */
+ /* Make sure that SCTP_STATUS getsockopt on a socket with no
+ * association fails.
+ */
+ optlen = sizeof(struct sctp_status);
+ memset(&status, 0, optlen);
+ error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
+ &optlen);
+ if ((error != -1) && (errno != EINVAL))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) on a "
+ "socket with no assoc error:%d errno:%d",
+ error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_STATUS) on a socket with no assoc");
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &udp_svr_loop;
+ outmessage.msg_namelen = sizeof(udp_svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on udp_svr_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ udp_svr_associd = sac->sac_assoc_id;
+
+ /* Get the communication up message on udp_clt_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ udp_clt_associd = sac->sac_assoc_id;
+
+ /* Get the first message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+
+ /* Get SCTP_STATUS for udp_clt_sk's given association. */
+ optlen = sizeof(struct sctp_status);
+ memset(&status, 0, optlen);
+ status.sstat_assoc_id = udp_clt_associd;
+ test_getsockopt(udp_clt_sk, SCTP_STATUS, &status, &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_STATUS)");
+
+ /* Make sure that SCTP_STATUS getsockopt with invalid associd fails. */
+ optlen = sizeof(struct sctp_status);
+ memset(&status, 0, optlen);
+ status.sstat_assoc_id = udp_svr_associd;
+ error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_STATUS, &status,
+ &optlen);
+ if ((error != -1) && (errno != EINVAL))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
+ "associd error: %d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_STATUS) with invalid associd");
+
+ /* Make sure that SCTP_STATUS getsockopt with NULL associd fails. */
+ optlen = sizeof(struct sctp_status);
+ memset(&status, 0, optlen);
+ status.sstat_assoc_id = 0;
+ error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
+ &optlen);
+ if ((error != -1) && (errno != EINVAL))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
+ "NULL associd error: %d errno:%d", error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_STATUS) with NULL associd");
+
+ /* Shut down the link. */
+ close(udp_clt_sk);
+
+ /* Get the shutdown complete notification. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ error = 0;
+ close(udp_svr_sk);
+
+ /* TEST #2: SCTP_EVENTS socket option and SCTP_SHUTDOWN_EVENT
+ * notification.
+ */
+ /* Create the two endpoints which will talk to each other. */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(udp_svr_sk);
+ test_enable_assoc_change(udp_clt_sk);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+ test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+ /* Mark udp_svr_sk as being able to accept new associations. */
+ test_listen(udp_svr_sk, 1);
+
+ /* Get the default events that are enabled on udp_svr_sk. */
+ optlen = sizeof(subscribe);
+ test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+ /* Get the default events that are enabled on udp_clt_sk. */
+ optlen = sizeof(subscribe);
+ test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_EVENTS)");
+
+ /* Disable all the events on udp_svr_sk and udp_clt_sk. */
+ memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
+ test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
+ sizeof(subscribe));
+ test_setsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe,
+ sizeof(subscribe));
+
+ tst_resm(TPASS, "setsockopt(SCTP_EVENTS)");
+
+ /* Get the updated list of enabled events on udp_svr_sk and
+ * udp_clt_sk.
+ */
+ optlen = sizeof(subscribe);
+ test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
+ optlen = sizeof(subscribe);
+ test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
+
+ /* Send a message. This will create the association. */
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+
+ /* Get the message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, 0, 0);
+ /* Verify that we received the msg without any ancillary data. */
+ if (inmessage.msg_controllen != 0)
+ tst_brkm(TBROK, tst_exit, "Receive unexpected ancillary"
+ "data");
+
+ /* Enable SCTP_SHUTDOWN_EVENTs on udp_svr_sk. */
+ memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
+ subscribe.sctp_shutdown_event = 1;
+ test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
+ sizeof(subscribe));
+
+ error = 0;
+ /* Shut down the link. */
+ close(udp_clt_sk);
+
+ /* Get the SHUTDOWN_EVENT notification on udp_svr_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_shutdown_event),
+ SCTP_SHUTDOWN_EVENT, 0);
+
+ tst_resm(TPASS, "setsockopt(SCTP_EVENTS) - SCTP_SHUTDOWN_EVENT");
+
+ close(udp_svr_sk);
+
+ /* TEST #3: whether sctp_opt_info equals */
+ /* Create the two endpoints which will talk to each other. */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(udp_svr_sk);
+ test_enable_assoc_change(udp_clt_sk);
+
+ /* Bind these sockets to the test ports. */
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+ test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+ /* Mark udp_svr_sk as being able to accept new associations. */
+ test_listen(udp_svr_sk, 1);
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &udp_svr_loop;
+ outmessage.msg_namelen = sizeof(udp_svr_loop);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
+
+ /* Get the communication up message on udp_clt_sk. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ udp_clt_associd = sac->sac_assoc_id;
+
+ /* Compare the SCTP_STATUS result between sctp_opt_info and
+ * getsockopt
+ */
+ {
+ struct sctp_status status1, status2;
+
+ memset(&status1, 0, sizeof(status1));
+ memset(&status2, 0, sizeof(status2));
+ optlen = sizeof(struct sctp_status);
+
+ /* Test SCTP_STATUS for udp_clt_sk's given association. */
+ error = sctp_opt_info(udp_clt_sk,udp_clt_associd,SCTP_STATUS,
+ (char *)&status1, &optlen);
+ if (error != 0)
+ tst_brkm(TBROK, tst_exit,
+ "sctp_opt_info(SCTP_STATUS): %s",
+ strerror(errno));
+
+ status2.sstat_assoc_id = udp_clt_associd;
+ error = getsockopt(udp_clt_sk, IPPROTO_SCTP, SCTP_STATUS,
+ (char *)&status2, &optlen);
+ if (error != 0)
+ tst_brkm(TBROK, tst_exit,
+ "getsockopt(SCTP_STATUS): %s",
+ strerror(errno));
+ if (strncmp((char *)&status1, (char *)&status2, optlen))
+ tst_brkm(TBROK, tst_exit, "sctp_opt_info(SCTP_STAUS)"
+ "doesn't match getsockopt(SCTP_STATUS)");
+
+ tst_resm(TPASS, "sctp_opt_info(SCTP_STATUS)");
+ }
+ error = 0;
+ /* Shut down the link. */
+ close(udp_svr_sk);
+ close(udp_clt_sk);
+
+ /* TEST #4: SCTP_INITMSG socket option. */
+ /* Create a socket. */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Bind this socket to the test port. */
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(udp_svr_sk);
+
+ /* Get the default parameters for association initialization. */
+ optlen = sizeof(initmsg);
+ test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_INITMSG)");
+
+ /* Change the parameters for association initialization. */
+ initmsg.sinit_num_ostreams = 5;
+ initmsg.sinit_max_instreams = 5;
+ initmsg.sinit_max_attempts = 3;
+ initmsg.sinit_max_init_timeo = 30;
+ test_setsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, sizeof(initmsg));
+
+ tst_resm(TPASS, "setsockopt(SCTP_INITMSG)");
+
+ /* Get the updated parameters for association initialization. */
+ optlen = sizeof(initmsg);
+ test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
+
+ close(udp_svr_sk);
+
+ /* TEST #5: SCTP_PEER_ADDR_PARAMS socket option. */
+ /* Create a socket. */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ /* Get the default parameters for this endpoint */
+ optlen = sizeof(paddrparams);
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_address.ss_family = AF_INET;
+ test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ &optlen);
+
+ dflt_pathmaxrxt = paddrparams.spp_pathmaxrxt;
+ tst_resm(TPASS, "getsockopt(SCTP_PEER_ADDR_PARAMS)");
+
+ /* Change the default parameters for this endpoint (socket) */
+ paddrparams.spp_hbinterval = 1000;
+ paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+ paddrparams.spp_sackdelay = 100;
+ test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ sizeof(paddrparams));
+
+ paddrparams.spp_pathmaxrxt = 0;
+
+ /* Get the updated default parameters for this endpoint. */
+ optlen = sizeof(paddrparams);
+ test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ &optlen);
+ if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt+1)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "mismatch");
+
+ value.assoc_id = 0;
+ optlen = sizeof(value);
+ test_getsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
+ &optlen);
+ if (value.assoc_value != 100)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DELAYED_ACK_TIME) "
+ "mismatch");
+
+ value.assoc_id = 0;
+ value.assoc_value = 250;
+ test_setsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
+ sizeof(value));
+ optlen = sizeof(paddrparams);
+ test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ &optlen);
+ if (paddrparams.spp_sackdelay != 250)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+ "mismatch");
+
+ tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME)");
+
+
+ /* Ensure that prior defaults are preserved for a new endpoint */
+ udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ optlen = sizeof(paddrparams);
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_address.ss_family = AF_INET;
+ test_getsockopt(udp_clt_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ &optlen);
+ if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "mismatch");
+
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS)");
+
+ /* Invalid assoc id */
+ paddrparams.spp_assoc_id = 1234;
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid associd error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid associd");
+
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+ test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+
+ test_listen(udp_svr_sk, 5);
+
+ test_enable_assoc_change(udp_svr_sk);
+ test_enable_assoc_change(udp_clt_sk);
+
+ /* Do a connect on a UDP-style socket and establish an association. */
+ test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+ /* Receive the COMM_UP notifications and get the associd's */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_hbinterval = 1000;
+ paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+ test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
+ sizeof(paddrparams));
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) - "
+ "one-to-many style valid associd valid address");
+
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_svr_loop, sizeof(udp_svr_loop));
+ paddrparams.spp_hbinterval = 1000;
+ paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid transport error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid transport");
+
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_hbinterval = 1000;
+ paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams) - 1);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid parameter length error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid parameter length");
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
+ &value,
+ sizeof(value) - 1);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+ "invalid parameter length error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+ "- one-to-many style invalid parameter length");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_sackdelay = 501;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid sack delay error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid sack delay");
+
+ value.assoc_id = sac->sac_assoc_id;
+ value.assoc_value = 501;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
+ &value,
+ sizeof(value));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+ "invalid sack delay error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
+ "- one-to-many style invalid sack delay");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_pathmtu = 511;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid path MTU error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid path MTU");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_flags = SPP_HB_ENABLE | SPP_HB_DISABLE;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid hb enable flags error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid hb enable flags");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_flags = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid PMTU discovery enable flags error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid PMTU discovery enable flags");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_assoc_id = sac->sac_assoc_id;
+ memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ paddrparams.spp_flags = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid sack delay enable flags error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid sack delay enable flags");
+
+ memset(&paddrparams, 0, sizeof(paddrparams));
+ paddrparams.spp_flags = SPP_HB_DEMAND;
+
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
+ &paddrparams,
+ sizeof(paddrparams));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "invalid hb demand error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
+ "- one-to-many style invalid hb demand");
+
+ close(udp_svr_sk);
+ close(udp_clt_sk);
+
+
+ /* TEST #6: SCTP_DEFAULT_SEND_PARAM socket option. */
+ /* Create and bind 2 UDP-style sockets(udp_svr_sk, udp_clt_sk) and
+ * 2 TCP-style sockets. (tcp_svr_sk, tcp_clt_sk)
+ */
+ udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ tcp_svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ tcp_clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(udp_svr_sk);
+ test_enable_assoc_change(udp_clt_sk);
+ test_enable_assoc_change(tcp_svr_sk);
+ test_enable_assoc_change(tcp_clt_sk);
+
+ test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+ test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
+ test_bind(tcp_svr_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
+ test_bind(tcp_clt_sk, &tcp_clt_loop.sa, sizeof(tcp_clt_loop));
+
+ /* Mark udp_svr_sk and tcp_svr_sk as being able to accept new
+ * associations.
+ */
+ test_listen(udp_svr_sk, 5);
+ test_listen(tcp_svr_sk, 5);
+
+ /* Set default send parameters on the unconnected UDP-style sockets. */
+ memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_udp_sk_dflt_param.sinfo_ppid = 1000;
+ test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
+ memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_udp_sk_dflt_param.sinfo_ppid = 1000;
+ test_setsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style socket");
+
+ /* Get default send parameters on the unconnected UDP-style socket. */
+ memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_udp_sk_dflt_param);
+ test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_udp_sk_dflt_param, &optlen);
+
+ /* Verify that the get param matches set param. */
+ if (set_udp_sk_dflt_param.sinfo_ppid !=
+ get_udp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ /* Get default send parameters on the unconnected UDP-style socket. */
+ memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_udp_sk_dflt_param);
+ test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_udp_sk_dflt_param, &optlen);
+
+ /* Verify that the get param matches set param. */
+ if (set_udp_sk_dflt_param.sinfo_ppid !=
+ get_udp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style socket");
+
+ /* Verify that trying to set send params with an invalid assoc id
+ * on an UDP-style socket fails.
+ */
+ memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_udp_sk_dflt_param.sinfo_ppid = 1000;
+ /* Invalid assoc id */
+ set_udp_sk_dflt_param.sinfo_assoc_id = 1234;
+ error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
+ &set_udp_sk_dflt_param,
+ sizeof(set_udp_sk_dflt_param));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "invalid associd error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "- one-to-many style invalid associd");
+
+ /* Do a connect on a UDP-style socket and establish an association. */
+ test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
+
+ /* Receive the COMM_UP notifications and get the associd's */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ udp_svr_associd = sac->sac_assoc_id;
+
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ udp_clt_associd = sac->sac_assoc_id;
+
+ /* Verify that trying to set send params with an assoc id not
+ * belonging to the socket on an UDP-style socket fails.
+ */
+ memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_udp_assoc_dflt_param.sinfo_ppid = 3000;
+ set_udp_assoc_dflt_param.sinfo_assoc_id = udp_clt_associd;
+ error = setsockopt(udp_svr_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
+ &set_udp_assoc_dflt_param,
+ sizeof(set_udp_assoc_dflt_param));
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "associd belonging to another socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style associd belonging to another socket");
+
+ /* Set default send parameters of an association on the listening
+ * UDP-style socket with a valid associd.
+ */
+ memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_udp_assoc_dflt_param.sinfo_ppid = 3000;
+ set_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd;
+ test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_udp_assoc_dflt_param,
+ sizeof(set_udp_assoc_dflt_param));
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style valid associd");
+
+ /* Get default send parameters of an association on the listening
+ * UDP-style socket with a valid associd.
+ */
+ memset(&get_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ get_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd ;
+ optlen = sizeof(get_udp_assoc_dflt_param);
+ test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_udp_assoc_dflt_param, &optlen);
+
+ /* Verify that the get param matches the set param. */
+ if (get_udp_assoc_dflt_param.sinfo_ppid !=
+ set_udp_assoc_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style valid associd");
+
+ /* Get default send parameters of an association on the connected
+ * UDP-style socket with zero associd. This should return the
+ * socket wide default parameters.
+ */
+ memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ get_udp_sk_dflt_param.sinfo_assoc_id = 0 ;
+ optlen = sizeof(get_udp_sk_dflt_param);
+ test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_udp_sk_dflt_param, &optlen);
+
+ /* Verify that the get param matches the socket-wide set param. */
+ if (get_udp_sk_dflt_param.sinfo_ppid !=
+ set_udp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style zero associd");
+
+ peeloff_sk = test_sctp_peeloff(udp_svr_sk, udp_svr_associd);
+
+ /* Get default send parameters of an association on the peeled off
+ * UDP-style socket. This should return the association's default
+ * parameters.
+ */
+ memset(&get_peeloff_assoc_dflt_param, 0,
+ sizeof(struct sctp_sndrcvinfo));
+ get_peeloff_assoc_dflt_param.sinfo_assoc_id = 0 ;
+ optlen = sizeof(get_peeloff_assoc_dflt_param);
+ test_getsockopt(peeloff_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_peeloff_assoc_dflt_param, &optlen);
+
+ /* Verify that the get param matches the association's set param. */
+ if (get_peeloff_assoc_dflt_param.sinfo_ppid !=
+ set_udp_assoc_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-many style peeled off socket");
+
+ /* Set default send parameters on the unconnected TCP-style sockets. */
+ memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_tcp_sk_dflt_param.sinfo_ppid = 2000;
+ /* Invalid assoc id, ignored on a TCP-style socket. */
+ set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
+ test_setsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_tcp_sk_dflt_param,
+ sizeof(set_tcp_sk_dflt_param));
+
+ /* Set default send parameters on the unconnected TCP-style sockets. */
+ memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_tcp_sk_dflt_param.sinfo_ppid = 2000;
+ /* Invalid assoc id, ignored on a TCP-style socket. */
+ set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
+ test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_tcp_sk_dflt_param,
+ sizeof(set_tcp_sk_dflt_param));
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-one style socket");
+
+ /* Get default send parameters on the unconnected TCP-style socket. */
+ memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_tcp_sk_dflt_param);
+ test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_tcp_sk_dflt_param, &optlen);
+
+ /* Verify that the get param matches set param. */
+ if (set_tcp_sk_dflt_param.sinfo_ppid !=
+ get_tcp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ /* Get default send parameters on the unconnected TCP-style socket. */
+ memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_tcp_sk_dflt_param);
+ test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_tcp_sk_dflt_param, &optlen);
+
+ /* Verify that the get param matches set param. */
+ if (set_tcp_sk_dflt_param.sinfo_ppid !=
+ get_tcp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-one style socket");
+
+ /* Do a connect on a TCP-style socket and establish an association. */
+ test_connect(tcp_clt_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
+
+ /* Set default send parameters of an association on the connected
+ * TCP-style socket.
+ */
+ memset(&set_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ set_tcp_assoc_dflt_param.sinfo_ppid = 4000;
+ set_tcp_assoc_dflt_param.sinfo_assoc_id = 0;
+ test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &set_tcp_assoc_dflt_param,
+ sizeof(set_tcp_assoc_dflt_param));
+
+ tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-one style assoc");
+
+ /* Get default send parameters of an association on the connected
+ * TCP-style socket.
+ */
+ memset(&get_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_tcp_assoc_dflt_param);
+ test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_tcp_assoc_dflt_param, &optlen);
+
+ if (set_tcp_assoc_dflt_param.sinfo_ppid !=
+ get_tcp_assoc_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ /* Get default send parameters on the connected TCP-style socket. */
+ memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_tcp_sk_dflt_param);
+ test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_tcp_sk_dflt_param, &optlen);
+
+ /* Verify that the get parameters returned matches the set param
+ * set for the association, not the socket-wide param.
+ */
+ if ((get_tcp_sk_dflt_param.sinfo_ppid ==
+ set_tcp_sk_dflt_param.sinfo_ppid) ||
+ (get_tcp_sk_dflt_param.sinfo_ppid !=
+ set_tcp_assoc_dflt_param.sinfo_ppid))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ /* Get default send parameters on the listening TCP-style socket. */
+ memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_tcp_sk_dflt_param);
+ test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_tcp_sk_dflt_param, &optlen);
+
+ /* Verify that the get parameters returned matches the socket-wide
+ * set param.
+ */
+ if (get_tcp_sk_dflt_param.sinfo_ppid !=
+ set_tcp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-one style assoc");
+
+ accept_sk = test_accept(tcp_svr_sk, NULL, &addrlen);
+
+ /* Get default send parameters of an association on the accepted
+ * TCP-style socket.
+ */
+ memset(&get_accept_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
+ optlen = sizeof(get_accept_assoc_dflt_param);
+ test_getsockopt(accept_sk, SCTP_DEFAULT_SEND_PARAM,
+ &get_accept_assoc_dflt_param, &optlen);
+
+ error = 0;
+
+ /* Verify that the get parameters returned matches the socket-wide
+ * set param.
+ */
+ if (get_tcp_sk_dflt_param.sinfo_ppid !=
+ set_tcp_sk_dflt_param.sinfo_ppid)
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
+ "mismatch.");
+
+ tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
+ "one-to-one style accepted socket");
+
+ /* TEST #7: SCTP_GET_PEER_ADDR_INFO socket option. */
+ /* Try 0 associd and 0 addr */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+ &pinfo, &optlen);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+ "null associd, null addr error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "null associd and null addr");
+
+ /* Try valid associd, but 0 addr */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ pinfo.spinfo_assoc_id = udp_clt_associd;
+ error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+ &pinfo, &optlen);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+ "valid associd, null addr error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "valid associd and null addr");
+
+ /* Try valid associd, invalid addr */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ pinfo.spinfo_assoc_id = udp_clt_associd;
+ memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
+ &pinfo, &optlen);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
+ "valid associd, invalid addr error:%d, errno:%d\n",
+ error, errno);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "valid associd and invalid addr");
+
+ /* Try valid associd, valid addr */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ pinfo.spinfo_assoc_id = udp_clt_associd;
+ memcpy(&pinfo.spinfo_address, &udp_svr_loop, sizeof(udp_svr_loop));
+ test_getsockopt(udp_clt_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "valid associd and valid addr");
+
+ /* Try valid addr, peeled off socket */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ pinfo.spinfo_assoc_id = 0;
+ memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
+ test_getsockopt(peeloff_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "valid associd and valid addr peeled off socket");
+
+ /* Try valid addr, TCP-style accept socket */
+ memset(&pinfo, 0, sizeof(pinfo));
+ optlen = sizeof(pinfo);
+ pinfo.spinfo_assoc_id = 0;
+ memcpy(&pinfo.spinfo_address, &tcp_clt_loop, sizeof(tcp_clt_loop));
+ error = test_getsockopt(accept_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo,
+ &optlen);
+
+ tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
+ "valid associd and valid addr accepted socket");
+
+ close(udp_svr_sk);
+ close(udp_clt_sk);
+ close(tcp_svr_sk);
+ close(tcp_clt_sk);
+ close(accept_sk);
+ close(peeloff_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_tcp_style.c b/src/func_tests/test_tcp_style.c
new file mode 100644
index 0000000..f4f835a
--- /dev/null
+++ b/src/func_tests/test_tcp_style.c
@@ -0,0 +1,463 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * This file is part of the SCTP kernel Implementation
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/* This is a kernel test to verify the TCP-style socket interfaces. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 22;
+int TST_CNT = 0;
+
+#define MAX_CLIENTS 10
+
+int
+main(int argc, char *argv[])
+{
+ int clt_sk[MAX_CLIENTS], accept_sk[MAX_CLIENTS];
+ int listen_sk, clt2_sk, accept2_sk;
+ sockaddr_storage_t clt_loop[MAX_CLIENTS];
+ sockaddr_storage_t svr_loop, accept_loop, clt2_loop;
+ socklen_t addrlen;
+ int error, i;
+ char *message = "hello, world!\n";
+ char msgbuf[100];
+ int pf_class;
+ struct pollfd poll_fd;
+ fd_set set;
+ struct msghdr outmessage;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct iovec out_iov;
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct msghdr inmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char *big_buffer;
+ struct iovec iov;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Initialize the server and client addresses. */
+#if TEST_V6
+ pf_class = PF_INET6;
+ svr_loop.v6.sin6_family = AF_INET6;
+ svr_loop.v6.sin6_addr = in6addr_loopback;
+ svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_loop[i].v6.sin6_family = AF_INET6;
+ clt_loop[i].v6.sin6_addr = in6addr_loopback;
+ clt_loop[i].v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+ }
+ clt2_loop.v6.sin6_family = AF_INET6;
+ clt2_loop.v6.sin6_addr = in6addr_loopback;
+ clt2_loop.v6.sin6_port = htons(SCTP_TESTPORT_2 + i);
+#else
+ pf_class = PF_INET;
+ svr_loop.v4.sin_family = AF_INET;
+ svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_loop[i].v4.sin_family = AF_INET;
+ clt_loop[i].v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt_loop[i].v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+ }
+ clt2_loop.v4.sin_family = AF_INET;
+ clt2_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ clt2_loop.v4.sin_port = htons(SCTP_TESTPORT_2 + i);
+#endif
+
+ /* Create and bind the listening server socket. */
+ listen_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(listen_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ /* Mark listen_sk as being able to accept new associations. */
+ test_listen(listen_sk, MAX_CLIENTS-1);
+
+ /* Create and bind the client sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ clt_sk[i] = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(clt_sk[i], &clt_loop[i].sa, sizeof(clt_loop[i]));
+ }
+ clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop));
+
+ addrlen = sizeof(accept_loop);
+ /* Try to do accept on a non-listening socket. It should fail. */
+ error = accept(clt_sk[0], &accept_loop.sa, &addrlen);
+ if ((-1 != error) && (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "accept on non-listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept on non-listening socket");
+
+ /* Try to do a connect from a listening socket. It should fail. */
+ error = connect(listen_sk, (struct sockaddr *)&clt_loop[0],
+ sizeof(clt_loop[0]));
+ if ((-1 != error) && (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connect to non-listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect to non-listening socket");
+
+ /* Do a blocking connect from clt_sk's to listen_sk */
+ for (i = 0; i < MAX_CLIENTS; i++)
+ test_connect(clt_sk[i], &svr_loop.sa, sizeof(svr_loop));
+
+ tst_resm(TPASS, "connect to listening socket");
+
+ /* Verify that no more connect's can be done after the acceptq
+ * backlog has reached the max value.
+ */
+ error = connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop));
+ if ((-1 != error) && (ECONNREFUSED != errno))
+ tst_brkm(TBROK, tst_exit, "connect after max backlog "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect after max backlog");
+
+ /* Extract the associations on the listening socket as new sockets. */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ poll_fd.fd = listen_sk;
+ poll_fd.events = POLLIN;
+ poll_fd.revents = 0;
+ error = poll(&poll_fd, 1, -1);
+ if ((1 != error) && (1 != poll_fd.revents))
+ tst_brkm(TBROK, tst_exit, "Unexpected return value "
+ "with poll, error:%d errno:%d, revents:%d",
+ error, errno, poll_fd.revents);
+
+ addrlen = sizeof(accept_loop);
+ accept_sk[i] = test_accept(listen_sk, &accept_loop.sa,
+ &addrlen);
+ }
+
+ tst_resm(TPASS, "accept from listening socket");
+
+ /* Try to do a connect on an established socket. It should fail. */
+ error = connect(accept_sk[0], &clt_loop[0].sa, sizeof(clt_loop[0]));
+ if ((-1 != error) || (EISCONN != errno))
+ tst_brkm(TBROK, tst_exit, "connect on an established socket "
+ "error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "connect on an established socket");
+
+ /* Try to do accept on an established socket. It should fail. */
+ error = accept(accept_sk[0], &accept_loop.sa, &addrlen);
+ if ((-1 != error) && (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "accept on an established socket "
+ "error:%d errno:%d", error, errno);
+
+ error = accept(clt_sk[0], &accept_loop.sa, &addrlen);
+ if ((-1 != error) && (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "accept on an established socket "
+ "failure: error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "accept on an established socket");
+
+ /* Send and receive a message from the client sockets to the accepted
+ * sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ test_send(clt_sk[i], message, strlen(message), 0);
+ test_recv(accept_sk[i], msgbuf, 100, 0);
+ }
+
+ tst_resm(TPASS, "client sockets -> accepted sockets");
+
+ /* Send and receive a message from the accepted sockets to the client
+ * sockets.
+ */
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ test_send(accept_sk[i], message, strlen(message), 0);
+ test_recv(clt_sk[i], msgbuf, 100, 0);
+ }
+
+ tst_resm(TPASS, "accepted sockets -> client sockets");
+
+ /* Sending a message on a listening socket should fail. */
+ error = send(listen_sk, message, strlen(message), MSG_NOSIGNAL);
+ if ((-1 != error) || (EPIPE != errno))
+ tst_brkm(TBROK, tst_exit, "send on a listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "send on a listening socket");
+
+ /* Trying to receive a message on a listening socket should fail. */
+ error = recv(listen_sk, msgbuf, 100, 0);
+ if ((-1 != error) || (ENOTCONN != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a listening socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "recv on a listening socket");
+
+ /* TESTCASES for shutdown() */
+ errno = 0;
+ test_send(accept_sk[0], message, strlen(message), 0);
+
+ /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+ test_enable_assoc_change(clt_sk[0]);
+
+ /* Do a SHUT_WR on clt_sk[0] to disable any new sends. */
+ test_shutdown(clt_sk[0], SHUT_WR);
+
+ /* Reading on a socket that has received SHUTDOWN should return 0
+ * indicating EOF.
+ */
+ error = recv(accept_sk[0], msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN received socket "
+ "error:%d errno:%d", error, errno);
+
+ tst_resm(TPASS, "recv on a SHUTDOWN received socket");
+
+ /* Read the pending message on clt_sk[0] that was received before
+ * SHUTDOWN call.
+ */
+ test_recv(clt_sk[0], msgbuf, 100, 0);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+ inmessage.msg_controllen = sizeof(incmsg);
+
+ /* Receive the SHUTDOWN_COMP notification as they are enabled. */
+ error = test_recvmsg(clt_sk[0], &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ tst_resm(TPASS, "recv SHUTDOWN_COMP notification on a SHUT_WR socket");
+
+ /* No more messages and the association is SHUTDOWN, should fail. */
+ error = recv(clt_sk[0], msgbuf, 100, 0);
+ if ((-1 != error) || (ENOTCONN != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUTDOWN sent socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "recv on a SHUTDOWN sent socket");
+
+ errno = 0;
+
+ /* Do a SHUT_RD on clt_sk[1] to disable any new receives. */
+ test_shutdown(clt_sk[1], SHUT_RD);
+
+ error = recv(clt_sk[1], msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+ "error:%d, errno:%d", error, errno);
+
+ /* Sending a message on SHUT_RD socket. */
+ test_send(clt_sk[1], message, strlen(message), 0);
+
+ /* Receive the message sent on SHUT_RD socket. */
+ test_recv(accept_sk[1], msgbuf, 100, 0);
+
+ /* Send a message to the SHUT_RD socket. */
+ test_send(accept_sk[1], message, strlen(message), 0);
+
+ /* We should not receive the message as the socket is SHUT_RD */
+ error = recv(clt_sk[1], msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RD socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "recv on a SHUT_RD socket");
+
+ /* Do a SHUT_RDWR on clt_sk[2] to disable any new sends/receives. */
+ test_shutdown(clt_sk[2], SHUT_RDWR);
+
+ error = recv(accept_sk[2], msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+ "error:%d, errno:%d", error, errno);
+
+ error = recv(clt_sk[2], msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "recv on a SHUT_RDWR socket "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "recv on a SHUT_RDWR socket");
+
+ error = 0;
+
+ for (i = 0; i < MAX_CLIENTS; i++)
+ close(clt_sk[i]);
+ for (i = 0; i < MAX_CLIENTS; i++)
+ close(accept_sk[i]);
+
+ /* Test case to verify accept of a CLOSED association. */
+ /* Do a connect, send and a close to ESTABLISH and CLOSE an
+ * association on the listening socket.
+ */
+ test_connect(clt2_sk, &svr_loop.sa, sizeof(svr_loop));
+
+ test_send(clt2_sk, message, strlen(message), 0);
+
+ close(clt2_sk);
+
+ FD_ZERO(&set);
+ FD_SET(listen_sk, &set);
+
+ error = select(listen_sk + 1, &set, NULL, NULL, NULL);
+ if (1 != error)
+ tst_brkm(TBROK, tst_exit, "select error:%d, "
+ "errno: %d", error, errno);
+
+ /* Now accept the CLOSED association waiting on the listening
+ * socket.
+ */
+ accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen);
+
+ /* Receive the message sent before doing a close. */
+ test_recv(accept2_sk, msgbuf, 100, 0);
+
+ /* Receive EOF indication as there are no more messages and the
+ * socket is SHUTDOWN.
+ */
+ error = recv(accept2_sk, msgbuf, 100, 0);
+ if ((0 != error) || (0 != errno))
+ tst_brkm(TBROK, tst_exit, "Unexpected error return on "
+ "recv(error:%d, errno:%d)", error, errno);
+
+ tst_resm(TPASS, "accept of a CLOSED association");
+
+ /* Trying to send a message over the CLOSED association should
+ * generate EPIPE.
+ */
+ error = send(accept2_sk, message, strlen(message), MSG_NOSIGNAL);
+ if ((-1 != error) || (EPIPE != errno))
+ tst_brkm(TBROK, tst_exit, "send to a CLOSED association "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "send to a CLOSED association");
+
+ error = 0;
+ close(accept2_sk);
+
+ /* Verify that auto-connect can be done on a TCP-style socket using
+ * sendto/sendmsg.
+ */
+ clt2_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
+ test_bind(clt2_sk, &clt2_loop.sa, sizeof(clt2_loop));
+
+ /* Do a sendto() without a connect() */
+ test_sendto(clt2_sk, message, strlen(message), 0, &svr_loop.sa,
+ sizeof(svr_loop));
+
+ accept2_sk = test_accept(listen_sk, &accept_loop.sa, &addrlen);
+
+ test_recv(accept2_sk, msgbuf, 100, 0);
+
+ tst_resm(TPASS, "auto-connect using sendto");
+
+ outmessage.msg_name = &svr_loop;
+ outmessage.msg_namelen = sizeof(svr_loop);
+ outmessage.msg_iov = NULL;
+ outmessage.msg_iovlen = 0;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ /* Verify that SCTP_EOF cannot be used to shutdown an association
+ * on a TCP-style socket.
+ */
+ sinfo->sinfo_flags |= SCTP_EOF;
+ error = sendmsg(clt2_sk, &outmessage, 0);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sendmsg with SCTP_EOF flag");
+
+ /* Verify that SCTP_ABORT cannot be used to abort an association
+ * on a TCP-style socket.
+ */
+ sinfo->sinfo_flags |= SCTP_ABORT;
+ error = sendmsg(clt2_sk, &outmessage, 0);
+ if ((-1 != error) || (EINVAL != errno))
+ tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag "
+ "error:%d, errno:%d", error, errno);
+
+ tst_resm(TPASS, "sendmsg with SCTP_ABORT flag");
+
+ /* Verify that a normal message can be sent using sendmsg. */
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ out_iov.iov_base = message;
+ out_iov.iov_len = strlen(message) + 1;
+ sinfo->sinfo_flags = 0;
+ test_sendmsg(clt2_sk, &outmessage, 0, strlen(message)+1);
+
+ test_recv(accept2_sk, msgbuf, 100, 0);
+
+ tst_resm(TPASS, "sendmsg with no flags");
+
+ close(clt2_sk);
+ close(accept2_sk);
+ close(listen_sk);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/func_tests/test_timetolive.c b/src/func_tests/test_timetolive.c
new file mode 100644
index 0000000..58d76f0
--- /dev/null
+++ b/src/func_tests/test_timetolive.c
@@ -0,0 +1,395 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+/*
+ * This is a basic functional test for the SCTP kernel
+ * implementation of sndrcvinfo.sinfo_timetolive.
+ *
+ * 1) Create two sockets, the listening socket sets its RECVBUF small
+ * 2) Create a connection. Send enough data to the non-reading listener
+ * to fill the RCVBUF.
+ * 5) Set sinfo_timetolive on a message and send.
+ * 6) Disable sinfo_timetolive on a message and send.
+ * 7) Wait sinfo_timetolive.
+ * 8) Read out all the data at the receiver.
+ * 9) Make sure timed out message did not make it.
+ * 10) Make sure that the message with no timeout makes it to the receiver.
+ *
+ * Also test with SEND_FAILED notifications. Also, use a fragmented
+ * message so as to also exercise the SEND_FAILED of fragmentation
+ * code.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+char *TCID = __FILE__;
+int TST_TOTAL = 6;
+int TST_CNT = 0;
+
+/* This is the size of our RCVBUF */
+#define SMALL_RCVBUF 3000
+
+/* MAX segment size */
+#define SMALL_MAXSEG 500
+
+/* RWND_SLOP is the extra data that fills up the rwnd */
+#define RWND_SLOP 100
+static char *fillmsg = NULL;
+static char *ttlmsg = "This should time out!\n";
+static char *nottlmsg = "This should NOT time out!\n";
+static char ttlfrag[SMALL_MAXSEG*3] = {0};
+static char *message = "Hello world\n";
+
+int main(int argc, char *argv[])
+{
+ int sk1, sk2;
+ sockaddr_storage_t loop1;
+ sockaddr_storage_t loop2;
+ struct iovec iov;
+ struct msghdr inmessage;
+ struct msghdr outmessage;
+ char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct iovec out_iov;
+ int error;
+ int pf_class;
+ uint32_t ppid;
+ uint32_t stream;
+ sctp_assoc_t associd1;
+ struct sctp_assoc_change *sac;
+ struct sctp_event_subscribe subscribe;
+ char *big_buffer;
+ int offset;
+ struct sctp_send_failed *ssf;
+ socklen_t len; /* Really becomes 2xlen when set. */
+ int orig_len;
+ struct sctp_status gstatus;
+
+ /* Rather than fflush() throughout the code, set stdout to
+ * be unbuffered.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* Set some basic values which depend on the address family. */
+#if TEST_V6
+ pf_class = PF_INET6;
+
+ loop1.v6.sin6_family = AF_INET6;
+ loop1.v6.sin6_addr = in6addr_loopback;
+ loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v6.sin6_family = AF_INET6;
+ loop2.v6.sin6_addr = in6addr_loopback;
+ loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
+#else
+ pf_class = PF_INET;
+
+ loop1.v4.sin_family = AF_INET;
+ loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
+
+ loop2.v4.sin_family = AF_INET;
+ loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
+ loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
+#endif /* TEST_V6 */
+
+ /* Create the two endpoints which will talk to each other. */
+ sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+ sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+ len = sizeof(int);
+ error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &orig_len,
+ &len);
+ if (error)
+ tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s",
+ strerror(errno));
+ /* Set the MAXSEG to something smallish. */
+ {
+ int val = SMALL_MAXSEG;
+ test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val));
+ }
+
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ subscribe.sctp_send_failure_event = 1;
+ test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+ test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe));
+
+ /* Bind these sockets to the test ports. */
+ test_bind(sk1, &loop1.sa, sizeof(loop1));
+ test_bind(sk2, &loop2.sa, sizeof(loop2));
+
+ /*
+ * This code sets the associations RWND very small so we can
+ * fill it. It does this by manipulating the rcvbuf as follows:
+ * 1) Reduce the rcvbuf size on the socket
+ * 2) create an association so that we advertise rcvbuf/2 as
+ * our initial rwnd
+ */
+ len = SMALL_RCVBUF;
+ error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len,
+ sizeof(len));
+ if (error)
+ tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s",
+ strerror(errno));
+
+ /* Mark sk2 as being able to accept new associations. */
+ test_listen(sk2, 1);
+
+ /* Send the first message. This will create the association. */
+ outmessage.msg_name = &loop2;
+ outmessage.msg_namelen = sizeof(loop2);
+ outmessage.msg_iov = &out_iov;
+ outmessage.msg_iovlen = 1;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid = rand(); /* Choose an arbitrary value. */
+ stream = 1;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = message;
+ outmessage.msg_iov->iov_len = strlen(message) + 1;
+ test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
+
+ /* Initialize inmessage for all receives. */
+ big_buffer = test_malloc(REALLY_BIG);
+ memset(&inmessage, 0, sizeof(inmessage));
+ iov.iov_base = big_buffer;
+ iov.iov_len = REALLY_BIG;
+ inmessage.msg_iov = &iov;
+ inmessage.msg_iovlen = 1;
+ inmessage.msg_control = incmsg;
+
+ /* Get the communication up message on sk2. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+#if 0
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd2 = sac->sac_assoc_id;
+#endif
+
+ /* Get the communication up message on sk1. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
+ sac = (struct sctp_assoc_change *)iov.iov_base;
+ associd1 = sac->sac_assoc_id;
+
+ /* Get the first data message which was sent. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(message) + 1,
+ MSG_EOR, stream, ppid);
+
+ /* Figure out how big to make our fillmsg */
+ len = sizeof(struct sctp_status);
+ memset(&gstatus,0,sizeof(struct sctp_status));
+ gstatus.sstat_assoc_id = associd1;
+ error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
+
+ if (error)
+ tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s",
+ strerror(errno));
+ tst_resm(TINFO, "Creating fillmsg of size %d",
+ gstatus.sstat_rwnd+RWND_SLOP);
+ fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP);
+
+ /* Send a fillmsg */
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ ppid++;
+ stream++;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP);
+ fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0';
+ outmessage.msg_iov->iov_base = fillmsg;
+ outmessage.msg_iov->iov_len = gstatus.sstat_rwnd+RWND_SLOP;
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ sinfo->sinfo_assoc_id = associd1;
+ sinfo->sinfo_timetolive = 0;
+ test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL,
+ gstatus.sstat_rwnd+RWND_SLOP);
+
+ /* Now send the message with timeout. */
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = ttlmsg;
+ outmessage.msg_iov->iov_len = strlen(ttlmsg) + 1;
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ sinfo->sinfo_assoc_id = associd1;
+ sinfo->sinfo_timetolive = 2000;
+ test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(ttlmsg) + 1);
+
+ tst_resm(TPASS, "Send a message with timeout");
+
+ /* Next send a message with no timeout. */
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ outmessage.msg_iov->iov_base = nottlmsg;
+ outmessage.msg_iov->iov_len = strlen(nottlmsg) + 1;
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ sinfo->sinfo_assoc_id = associd1;
+ sinfo->sinfo_timetolive = 0;
+ test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, strlen(nottlmsg)+1);
+
+ tst_resm(TPASS, "Send a message with no timeout");
+
+ /* And finally a fragmented message that will time out. */
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_stream = stream;
+ memset(ttlfrag, 48, sizeof(ttlfrag)); /* 48 is the ascii of '0' */
+ ttlfrag[sizeof(ttlfrag)-1] = '\0';
+ outmessage.msg_iov->iov_base = ttlfrag;
+ outmessage.msg_iov->iov_len = sizeof(ttlfrag);
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ sinfo->sinfo_assoc_id = associd1;
+ sinfo->sinfo_timetolive = 2000;
+ test_sendmsg(sk1, &outmessage, MSG_NOSIGNAL, sizeof(ttlfrag));
+
+ tst_resm(TPASS, "Send a fragmented message with timeout");
+
+ /* Sleep waiting for the message to time out. */
+ tst_resm(TINFO, " ** SLEEPING for 3 seconds **");
+ sleep(3);
+
+ /* Read the fillmsg snuck in between the ttl'd messages. */
+ do {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ } while (!(inmessage.msg_flags & MSG_EOR));
+
+ /* Now get the message that did NOT time out. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_data(&inmessage, error, strlen(nottlmsg) + 1,
+ MSG_EOR, stream, ppid);
+ if (0 != strncmp(iov.iov_base, nottlmsg, strlen(nottlmsg)+1))
+ tst_brkm(TBROK, tst_exit, "Received Wrong Message !!!");
+
+ tst_resm(TPASS, "Receive message with no timeout");
+
+ /* Get the SEND_FAILED notification for the message that DID
+ * time out.
+ */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_send_failed) +
+ strlen(ttlmsg) + 1,
+ SCTP_SEND_FAILED, 0);
+ ssf = (struct sctp_send_failed *)iov.iov_base;
+ if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1))
+ tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+
+ tst_resm(TPASS, "Receive SEND_FAILED for message with timeout");
+
+ /* Get the SEND_FAILED notification for the fragmented message that
+ * DID time out.
+ */
+ offset = 0;
+ do {
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_send_failed) +
+ SMALL_MAXSEG,
+ SCTP_SEND_FAILED, 0);
+ ssf = (struct sctp_send_failed *)iov.iov_base;
+ if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data,
+ SMALL_MAXSEG))
+ tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch");
+ offset += SMALL_MAXSEG;
+ } while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST_FRAG */
+
+ tst_resm(TPASS, "Receive SEND_FAILED for fragmented message with "
+ "timeout");
+
+ /* Shut down the link. */
+ close(sk1);
+
+ /* Get the shutdown complete notification. */
+ inmessage.msg_controllen = sizeof(incmsg);
+ error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
+ test_check_msg_notification(&inmessage, error,
+ sizeof(struct sctp_assoc_change),
+ SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
+
+ close(sk2);
+
+ /* Indicate successful completion. */
+ return 0;
+}
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 0000000..38abaec
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,5 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+SUBDIRS = netinet
diff --git a/src/include/netinet/Makefile.am b/src/include/netinet/Makefile.am
new file mode 100644
index 0000000..965db8c
--- /dev/null
+++ b/src/include/netinet/Makefile.am
@@ -0,0 +1,14 @@
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+libcnetinetdir = $(includedir)/netinet
+
+
+## FIXME: Your stuff here
+
+# Supposing this is part of the development package, header for our
+# API.
+include_HEADERS =
+
+libcnetinet_HEADERS = sctp.h
diff --git a/src/include/netinet/sctp.h.in b/src/include/netinet/sctp.h.in
new file mode 100644
index 0000000..2009f1c
--- /dev/null
+++ b/src/include/netinet/sctp.h.in
@@ -0,0 +1,188 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sctp.h
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * Linux Kernel SCTP Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with SCTP in kernel.
+ *
+ * This header represents the structures and constants needed to support
+ * the SCTP Extension to the Sockets API.
+ *
+ * (C) Copyright IBM Corp. 2001, 2004
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * R. Stewart <randall@sctp.chicago.il.us>
+ * K. Morneau <kmorneau@cisco.com>
+ * Q. Xie <qxie1@email.mot.com>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Jon Grimm <jgrimm@austin.ibm.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Inaky Perez-Gonzalez <inaky.gonzalez@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ * Vlad Yasevich <vladislav.yasevich@hp.com>
+ */
+
+#ifndef __linux_sctp_h__
+#define __linux_sctp_h__
+
+#include <stdint.h>
+#include <linux/types.h>
+#include <sys/socket.h>
+#include <linux/sctp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Socket option layer for SCTP */
+#ifndef SOL_SCTP
+#define SOL_SCTP 132
+#endif
+
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+/* 9. Preprocessor constants */
+#define HAVE_SCTP
+#define HAVE_KERNEL_SCTP
+#define HAVE_SCTP_MULTIBUF
+#define HAVE_SCTP_NOCONNECT
+#define HAVE_SCTP_PRSCTP
+#define HAVE_SCTP_ADDIP
+#define HAVE_SCTP_CANSET_PRIMARY
+
+#undef HAVE_SCTP_STREAM_RESET_EVENT
+#undef HAVE_SCTP_STREAM_RECONFIG
+#undef HAVE_SCTP_PEELOFF_FLAGS
+#undef HAVE_SCTP_PDAPI_EVENT_PDAPI_STREAM
+#undef HAVE_SCTP_PDAPI_EVENT_PDAPI_SEQ
+#undef HAVE_SCTP_SENDV
+#undef HAVE_SCTP_AUTH_NO_AUTH
+#undef HAVE_SCTP_SPP_IPV6_FLOWLABEL
+#undef HAVE_SCTP_SPP_DSCP
+
+int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags);
+
+int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt,
+ sctp_assoc_t *id);
+
+int sctp_peeloff(int sd, sctp_assoc_t assoc_id);
+int sctp_peeloff_flags(int sd, sctp_assoc_t assoc_id, unsigned flags);
+
+/* Prototype for the library function sctp_opt_info defined in
+ * API 7. Socket Options.
+ */
+int sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size);
+
+/* Get all peer address on a socket. This is a new SCTP API
+ * described in the section 8.3 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+
+/* Frees all resources allocated by sctp_getpaddrs(). This is a new SCTP API
+ * described in the section 8.4 of the Sockets API Extensions for SCTP.
+ */
+int sctp_freepaddrs(struct sockaddr *addrs);
+
+/* Get all locally bound address on a socket. This is a new SCTP API
+ * described in the section 8.5 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+
+/* Frees all resources allocated by sctp_getladdrs(). This is a new SCTP API
+ * described in the section 8.6 of the Sockets API Extensions for SCTP.
+ */
+int sctp_freeladdrs(struct sockaddr *addrs);
+
+/* This library function assists the user with the advanced features
+ * of SCTP. This is a new SCTP API described in the section 8.7 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * sendmsg() interface.
+ */
+int sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to,
+ socklen_t tolen, uint32_t ppid, uint32_t flags,
+ uint16_t stream_no, uint32_t timetolive, uint32_t context);
+
+/* This library function assist the user with sending a message without
+ * dealing directly with the CMSG header.
+ */
+int sctp_send(int s, const void *msg, size_t len,
+ const struct sctp_sndrcvinfo *sinfo, int flags);
+
+/* This library function assists the user with the advanced features
+ * of SCTP. This is a new SCTP API described in the section 8.8 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * recvmsg() interface.
+ */
+int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from,
+ socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo,
+ int *msg_flags);
+
+/* Return the address length for an address family. */
+int sctp_getaddrlen(sa_family_t family);
+
+
+#ifdef HAVE_SCTP_SENDV
+/* sendv infotype */
+enum {
+ SCTP_SENDV_NOINFO,
+ SCTP_SENDV_SNDINFO,
+ SCTP_SENDV_PRINFO,
+ SCTP_SENDV_AUTHINFO,
+ SCTP_SENDV_SPA
+};
+
+/* sendv_flags */
+#define SCTP_SEND_SNDINFO_VALID 0x1
+#define SCTP_SEND_PRINFO_VALID 0x2
+#define SCTP_SEND_AUTHINFO_VALID 0x4
+#endif
+
+struct sctp_sendv_spa {
+ uint32_t sendv_flags;
+ struct sctp_sndinfo sendv_sndinfo;
+#ifdef HAVE_SCTP_SENDV
+ struct sctp_prinfo sendv_prinfo;
+ struct sctp_authinfo sendv_authinfo;
+#endif
+};
+
+#ifdef HAVE_SCTP_SENDV
+int sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+ struct sockaddr *addrs, int addrcnt, void *info,
+ socklen_t infolen, unsigned int infotype, int flags);
+
+/* recvv infotype */
+enum {
+ SCTP_RECVV_NOINFO,
+ SCTP_RECVV_RCVINFO,
+ SCTP_RECVV_NXTINFO,
+ SCTP_RECVV_RN
+};
+
+struct sctp_recvv_rn {
+ struct sctp_rcvinfo recvv_rcvinfo;
+ struct sctp_nxtinfo recvv_nxtinfo;
+};
+
+int sctp_recvv(int s, const struct iovec *iov, int iovlen,
+ struct sockaddr *from, socklen_t *fromlen, void *info,
+ socklen_t *infolen, unsigned int *infotype, int *flags);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __linux_sctp_h__ */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 0000000..1296caa
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,15 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I$(top_builddir)/src/include
+
+lib_LTLIBRARIES = libsctp.la
+
+libsctp_la_SOURCES = bindx.c connectx.c peeloff.c opt_info.c \
+ addrs.c sendmsg.c recvmsg.c Versions.map
+libsctp_la_LDFLAGS = -version-info \
+ @LIBSCTP_CURRENT@:@LIBSCTP_REVISION@:@LIBSCTP_AGE@ \
+ -Wl,--version-script=$(srcdir)/Versions.map
diff --git a/src/lib/Versions.map b/src/lib/Versions.map
new file mode 100644
index 0000000..7faad5d
--- /dev/null
+++ b/src/lib/Versions.map
@@ -0,0 +1,28 @@
+VERS_1 {
+ global:
+ sctp_getpaddrs;
+ sctp_freepaddrs;
+ sctp_getladdrs;
+ sctp_freeladdrs;
+ sctp_getaddrlen;
+ sctp_bindx;
+ sctp_connectx;
+ sctp_opt_info;
+ sctp_peeloff;
+ sctp_recvmsg;
+ sctp_recvv;
+ sctp_sendmsg;
+ sctp_sendv;
+ sctp_send;
+
+ local:
+ *;
+};
+
+VERS_2 {
+ global: sctp_connectx;
+} VERS_1;
+
+VERS_3 {
+ global: sctp_connectx;
+} VERS_2;
diff --git a/src/lib/addrs.c b/src/lib/addrs.c
new file mode 100644
index 0000000..65f5222
--- /dev/null
+++ b/src/lib/addrs.c
@@ -0,0 +1,155 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * addrs.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2001-2002 Intel Corp.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ * Ivan Skytte Jørgensen <isj-sctp@i1.dk>
+ */
+
+#include <malloc.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * Common getsockopt() layer
+ * If the NEW getsockopt() API fails this function will fall back to using
+ * the old API
+ */
+static int
+sctp_getaddrs(int sd, sctp_assoc_t id, int optname_new,
+ struct sockaddr **addrs)
+{
+ int cnt, err;
+ socklen_t len;
+ size_t bufsize = 4096; /*enough for most cases*/
+
+ struct sctp_getaddrs *getaddrs = (struct sctp_getaddrs*)malloc(bufsize);
+ if(!getaddrs)
+ return -1;
+
+ for(;;) {
+ char *new_buf;
+
+ len = bufsize;
+ getaddrs->assoc_id = id;
+ err = getsockopt(sd, SOL_SCTP, optname_new, getaddrs, &len);
+ if (err == 0) {
+ /*got it*/
+ break;
+ }
+ if (errno != ENOMEM ) {
+ /*unknown error*/
+ free(getaddrs);
+ return -1;
+ }
+ /*expand buffer*/
+ if (bufsize > 128*1024) {
+ /*this is getting ridiculous*/
+ free(getaddrs);
+ errno = ENOBUFS;
+ return -1;
+ }
+ new_buf = realloc(getaddrs, bufsize+4096);
+ if (!new_buf) {
+ free(getaddrs);
+ return -1;
+ }
+ bufsize += 4096;
+ getaddrs = (struct sctp_getaddrs*)new_buf;
+ }
+
+ /* we skip traversing the list, allocating a new buffer etc. and enjoy
+ * a simple hack*/
+ cnt = getaddrs->addr_num;
+ memmove(getaddrs, getaddrs + 1, len);
+ *addrs = (struct sockaddr*)getaddrs;
+
+ return cnt;
+} /* sctp_getaddrs() */
+
+/* Get all peer address on a socket. This is a new SCTP API
+ * described in the section 8.3 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **addrs)
+{
+ return sctp_getaddrs(sd, id,
+ SCTP_GET_PEER_ADDRS,
+ addrs);
+} /* sctp_getpaddrs() */
+
+/* Frees all resources allocated by sctp_getpaddrs(). This is a new SCTP API
+ * described in the section 8.4 of the Sockets API Extensions for SCTP.
+ */
+int
+sctp_freepaddrs(struct sockaddr *addrs)
+{
+ free(addrs);
+ return 0;
+
+} /* sctp_freepaddrs() */
+
+/* Get all locally bound address on a socket. This is a new SCTP API
+ * described in the section 8.5 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **addrs)
+{
+ return sctp_getaddrs(sd, id,
+ SCTP_GET_LOCAL_ADDRS,
+ addrs);
+} /* sctp_getladdrs() */
+
+/* Frees all resources allocated by sctp_getladdrs(). This is a new SCTP API
+ * described in the section 8.6 of the Sockets API Extensions for SCTP.
+ */
+int
+sctp_freeladdrs(struct sockaddr *addrs)
+{
+ free(addrs);
+ return 0;
+
+} /* sctp_freeladdrs() */
+
+int
+sctp_getaddrlen(sa_family_t family)
+{
+ /* We could call into the kernel to see what it thinks the size should
+ * be, but hardcoding the address families here is: (a) faster,
+ * (b) easier, and (c) probably good enough for forseeable future.
+ */
+ switch(family) {
+ case AF_INET:
+ return sizeof(struct sockaddr_in);
+ case AF_INET6:
+ return sizeof(struct sockaddr_in6);
+ default:
+ /* Currently there is no defined error handling in
+ * draft-ietf-tsvwg-sctpsocket-13.txt.
+ * -1 might cause the application to overwrite buffer
+ * or misinterpret data. 0 is more likely to cause
+ * an endless loop.
+ */
+ return 0;
+ }
+}
diff --git a/src/lib/bindx.c b/src/lib/bindx.c
new file mode 100644
index 0000000..5f44874
--- /dev/null
+++ b/src/lib/bindx.c
@@ -0,0 +1,78 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * bindx.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 2002 Intel Corporation.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Inaky Perez-Gonzalez <inaky.gonzalez@intel.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/in.h>
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+/* Support the sctp_bindx() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 8.1.
+ *
+ * Instead of implementing through a socket call in sys_socketcall(),
+ * tunnel the request through setsockopt().
+ */
+int
+sctp_bindx(int fd, struct sockaddr *addrs, int addrcnt, int flags)
+{
+ int setsock_option = 0;
+ const char *addrbuf;
+ struct sockaddr *sa_addr;
+ socklen_t addrs_size = 0;
+ int i;
+
+ switch (flags) {
+ case SCTP_BINDX_ADD_ADDR:
+ setsock_option = SCTP_SOCKOPT_BINDX_ADD;
+ break;
+ case SCTP_BINDX_REM_ADDR:
+ setsock_option = SCTP_SOCKOPT_BINDX_REM;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ addrbuf = (char*)addrs;
+ for (i = 0; i < addrcnt; i++) {
+ sa_addr = (struct sockaddr *)addrbuf;
+ switch (sa_addr->sa_family) {
+ case AF_INET:
+ addrs_size += sizeof(struct sockaddr_in);
+ addrbuf += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ addrs_size += sizeof(struct sockaddr_in6);
+ addrbuf += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ return setsockopt(fd, SOL_SCTP, setsock_option, addrs, addrs_size);
+}
diff --git a/src/lib/connectx.c b/src/lib/connectx.c
new file mode 100644
index 0000000..5f4552b
--- /dev/null
+++ b/src/lib/connectx.c
@@ -0,0 +1,190 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * connectx.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt.
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2005
+ *
+ * Written or modified by:
+ * Frank Filz <ffilz@us.ibm.com>
+ */
+
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/in.h>
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_CONNECTX_* */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+/* Support the sctp_connectx() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 8.1.
+ *
+ * Instead of implementing through a socket call in sys_socketcall(),
+ * tunnel the request through setsockopt().
+ */
+static int __connectx_addrsize(const struct sockaddr *addrs,
+ const int addrcnt)
+{
+ const char *addrbuf;
+ const struct sockaddr *sa_addr;
+ int addrs_size = 0;
+ int i;
+
+ addrbuf = (char *)addrs;
+ for (i = 0; i < addrcnt; i++) {
+ sa_addr = (const struct sockaddr *)addrbuf;
+ switch (sa_addr->sa_family) {
+ case AF_INET:
+ addrs_size += sizeof(struct sockaddr_in);
+ addrbuf += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ addrs_size += sizeof(struct sockaddr_in6);
+ addrbuf += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ return addrs_size;
+}
+
+
+int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt)
+{
+ int addrs_size = __connectx_addrsize(addrs, addrcnt);
+
+ if (addrs_size < 0)
+ return addrs_size;
+
+ return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD, addrs,
+ addrs_size);
+}
+
+extern int sctp_connectx_orig (int)
+ __attribute ((alias ("__sctp_connectx")));
+
+
+static int __connectx(int fd, struct sockaddr *addrs, socklen_t addrs_size,
+ sctp_assoc_t *id)
+{
+ int status;
+
+ if (id)
+ *id = 0;
+
+ status = setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX, addrs,
+ addrs_size);
+
+ /* Normalize status and set association id */
+ if (status > 0) {
+ if (id)
+ *id = status;
+ return 0;
+ }
+
+ /* The error is something other then "Option not supported" */
+ if (status < 0 && errno != ENOPROTOOPT)
+ return status;
+
+ /* At this point, if the application wanted the id, we can't
+ * really provide it, so we can return ENOPROTOOPT.
+ */
+ if (id) {
+ errno = ENOPROTOOPT;
+ return -1;
+ }
+
+ /* Finally, try the old API */
+ return setsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX_OLD,
+ addrs, addrs_size);
+}
+
+int sctp_connectx2(int fd, struct sockaddr *addrs, int addrcnt,
+ sctp_assoc_t *id)
+{
+ int addrs_size = __connectx_addrsize(addrs, addrcnt);
+
+ if (addrs_size < 0)
+ return addrs_size;
+
+ return __connectx(fd, addrs, addrs_size, id);
+}
+
+int sctp_connectx3(int fd, struct sockaddr *addrs, int addrcnt,
+ sctp_assoc_t *id)
+{
+ int addrs_size = __connectx_addrsize(addrs, addrcnt);
+ int status;
+ struct sctp_getaddrs_old param;
+ socklen_t opt_len = sizeof(param);
+
+ if (addrs_size < 0)
+ return addrs_size;
+
+ /* First try the new socket api
+ * Because the id is returned in the option buffer we have prepend
+ * 32bit to it for the returned association id
+ */
+ param.assoc_id = 0;
+ param.addr_num = addrs_size;
+ param.addrs = addrs;
+ status = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_CONNECTX3,
+ ¶m, &opt_len);
+ if (status == 0 || errno == EINPROGRESS) {
+ /* Succeeded immediately, or initiated on non-blocking
+ * socket.
+ */
+ if (id)
+ *id = param.assoc_id;
+ }
+
+ if (errno != ENOPROTOOPT) {
+ /* No point in trying the fallbacks*/
+ return status;
+ }
+
+ /* The first incarnation of updated connectx api didn't work for
+ * non-blocking sockets. So if the application wants the association
+ * id and the socket is non-blocking, we can't really do anything.
+ */
+ if (id) {
+ /* Program wants the association-id returned. We can only do
+ * that if the socket is blocking */
+ status = fcntl(fd, F_GETFL);
+ if (status < 0)
+ return status;
+
+ if (status & O_NONBLOCK) {
+ /* Socket is non-blocking. Fail */
+ errno = ENOPROTOOPT;
+ return -1;
+ }
+ }
+
+ return __connectx(fd, addrs, addrs_size, id);
+}
+
+#define __SYMPFX(pfx, sym) #pfx sym
+#define _SYMPFX(pfx, sym) __SYMPFX(pfx, sym)
+#define SYMPFX(sym) _SYMPFX(__USER_LABEL_PREFIX__, #sym)
+#define SYMVER(name, name2) __asm__(".symver " SYMPFX(name) "," SYMPFX(name2))
+
+SYMVER(__sctp_connectx, sctp_connectx@);
+SYMVER(sctp_connectx_orig, sctp_connectx@VERS_1);
+SYMVER(sctp_connectx2, sctp_connectx@VERS_2);
+SYMVER(sctp_connectx3, sctp_connectx@@VERS_3);
diff --git a/src/lib/opt_info.c b/src/lib/opt_info.c
new file mode 100644
index 0000000..21c8307
--- /dev/null
+++ b/src/lib/opt_info.c
@@ -0,0 +1,62 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * opt_info.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code if to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2003
+ * Copyright (c) 2002 Intel Corporation.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ */
+
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+/* Support the sctp_opt_info() interface.
+ *
+ * See Sockets API Extensions for SCTP. Section 7.
+ *
+ * Pass sctp option information pass both in to and out of the SCTP stack.
+ * This is a new SCTP API described in the section 7 of the Sockets API
+ * Extensions for SCTP. This is implemented using the getsockopt() interface.
+ */
+int
+sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t *size)
+{
+ switch (opt) {
+ case SCTP_RTOINFO:
+ case SCTP_ASSOCINFO:
+ case SCTP_INITMSG:
+ case SCTP_NODELAY:
+ case SCTP_AUTOCLOSE:
+ case SCTP_PRIMARY_ADDR:
+ case SCTP_DISABLE_FRAGMENTS:
+ case SCTP_PEER_ADDR_PARAMS:
+ case SCTP_DEFAULT_SEND_PARAM:
+ case SCTP_EVENTS:
+ case SCTP_I_WANT_MAPPED_V4_ADDR:
+ case SCTP_MAXSEG:
+ case SCTP_STATUS:
+ case SCTP_GET_PEER_ADDR_INFO:
+ case SCTP_AUTH_ACTIVE_KEY:
+ case SCTP_PEER_AUTH_CHUNKS:
+ case SCTP_LOCAL_AUTH_CHUNKS:
+ *(sctp_assoc_t *)arg = id;
+ return getsockopt(sd, IPPROTO_SCTP, opt, arg, size);
+ default:
+ return ENOTSUP;
+ }
+
+} /* sctp_opt_info() */
diff --git a/src/lib/peeloff.c b/src/lib/peeloff.c
new file mode 100644
index 0000000..a4e1ed9
--- /dev/null
+++ b/src/lib/peeloff.c
@@ -0,0 +1,72 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * peeloff.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt.
+ *
+ * (C) Copyright IBM Corp. 2001, 2003
+ *
+ * Written or modified by:
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */
+#include <errno.h>
+
+#ifdef HAVE_SCTP_PEELOFF_FLAGS
+int
+sctp_peeloff_flags(int fd, sctp_assoc_t associd, unsigned flags)
+{
+ socklen_t peeloff_size = sizeof(sctp_peeloff_flags_arg_t);
+ sctp_peeloff_flags_arg_t peeloff;
+ int err;
+
+ if (!flags)
+ return sctp_peeloff(fd, associd);
+
+ peeloff.p_arg.associd = associd;
+ peeloff.p_arg.sd = 0;
+ peeloff.flags = flags;
+
+ err = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_PEELOFF_FLAGS, &peeloff,
+ &peeloff_size);
+
+ if (err < 0)
+ return err;
+
+ return peeloff.p_arg.sd;
+}
+#endif
+
+/* Branch off an association into a seperate socket. This is a new SCTP API
+ * described in the section 8.2 of the Sockets API Extensions for SCTP.
+ * This is implemented using the getsockopt() interface.
+ */
+int
+sctp_peeloff(int fd, sctp_assoc_t associd)
+{
+ socklen_t peeloff_size = sizeof(sctp_peeloff_arg_t);
+ sctp_peeloff_arg_t peeloff;
+ int err;
+
+ peeloff.associd = associd;
+ peeloff.sd = 0;
+
+ err = getsockopt(fd, SOL_SCTP, SCTP_SOCKOPT_PEELOFF, &peeloff,
+ &peeloff_size);
+
+ if (err < 0)
+ return err;
+
+ return peeloff.sd;
+}
diff --git a/src/lib/recvmsg.c b/src/lib/recvmsg.c
new file mode 100644
index 0000000..88fe061
--- /dev/null
+++ b/src/lib/recvmsg.c
@@ -0,0 +1,191 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sctp_recvmsg.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
+ *
+ * Copyright (c) 2003 International Business Machines, Corp.
+ *
+ * Written or modified by:
+ * Ryan Layer <rmlayer@us.ibm.com>
+ *
+ * An implementation may provide a library function (or possibly system
+ * call) to assist the user with the advanced features of SCTP. Note
+ * that in order for the sctp_sndrcvinfo structure to be filled in by
+ * sctp_recvmsg() the caller must enable the sctp_data_io_events with
+ * the SCTP_EVENTS option.
+ *
+ * sctp_recvmsg(). Its syntax is,
+ *
+ * int sctp_recvmsg(int s,
+ * void *msg,
+ * size_t len,
+ * struct sockaddr *from,
+ * socklen_t *fromlen,
+ * struct sctp_sndrcvinfo *sinfo,
+ * int *msg_flags)
+ *
+ *
+ * s - is the socket descriptor
+ * msg - is a message buffer to be filled.
+ * len - is the length of the message buffer.
+ * from - is a pointer to a address to be filled with
+ * the sender of this messages address.
+ * fromlen - is the from length.
+ * sinfo - A pointer to a sctp_sndrcvinfo structure
+ * to be filled upon receipt of the message.
+ * msg_flags - A pointer to a integer to be filled with
+ * any message flags (e.g. MSG_NOTIFICATION).
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h>
+
+int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from,
+ socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo,
+ int *msg_flags)
+{
+ int error;
+ struct iovec iov;
+ struct msghdr inmsg;
+ char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg = NULL;
+
+ memset(&inmsg, 0, sizeof (inmsg));
+
+ iov.iov_base = msg;
+ iov.iov_len = len;
+
+ inmsg.msg_name = from;
+ inmsg.msg_namelen = fromlen ? *fromlen : 0;
+ inmsg.msg_iov = &iov;
+ inmsg.msg_iovlen = 1;
+ inmsg.msg_control = incmsg;
+ inmsg.msg_controllen = sizeof(incmsg);
+
+ error = recvmsg(s, &inmsg, msg_flags ? *msg_flags : 0);
+ if (error < 0)
+ return error;
+
+ if (fromlen)
+ *fromlen = inmsg.msg_namelen;
+ if (msg_flags)
+ *msg_flags = inmsg.msg_flags;
+
+ if (!sinfo)
+ return error;
+
+ for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&inmsg, cmsg)){
+ if ((IPPROTO_SCTP == cmsg->cmsg_level) &&
+ (SCTP_SNDRCV == cmsg->cmsg_type))
+ break;
+ }
+
+ /* Copy sinfo. */
+ if (cmsg)
+ memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo));
+
+ return (error);
+}
+
+#ifdef HAVE_SCTP_SENDV
+int sctp_recvv(int s, const struct iovec *iov, int iovlen,
+ struct sockaddr *from, socklen_t *fromlen, void *info,
+ socklen_t *infolen, unsigned int *infotype, int *flags)
+{
+ char incmsg[CMSG_SPACE(sizeof(struct sctp_rcvinfo) +
+ sizeof(struct sctp_nxtinfo))];
+ int error, len, _infolen;
+ struct cmsghdr *cmsg;
+ struct msghdr inmsg;
+
+ memset(&inmsg, 0, sizeof(inmsg));
+
+ /* set from and iov */
+ inmsg.msg_name = from;
+ inmsg.msg_namelen = fromlen ? *fromlen : 0;
+ inmsg.msg_iov = (struct iovec *)iov;
+ inmsg.msg_iovlen = iovlen;
+ inmsg.msg_control = incmsg;
+ inmsg.msg_controllen = sizeof(incmsg);
+
+ error = recvmsg(s, &inmsg, flags ? *flags : 0);
+ if (error < 0)
+ return error;
+
+ /* set fromlen, frags */
+ if (fromlen)
+ *fromlen = inmsg.msg_namelen;
+
+ if (flags)
+ *flags = inmsg.msg_flags;
+
+ if (!info || !infotype || !infolen)
+ return error;
+
+ *infotype = SCTP_RECVV_NOINFO;
+ _infolen = *infolen;
+
+ /* set info and infotype */
+ for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&inmsg, cmsg)) {
+ if (cmsg->cmsg_level != IPPROTO_SCTP)
+ continue;
+
+ if (cmsg->cmsg_type == SCTP_RCVINFO) {
+ len = sizeof(struct sctp_rcvinfo);
+ if (*infotype == SCTP_RECVV_NOINFO) {
+ if (_infolen < len)
+ break;
+ memcpy(info, CMSG_DATA(cmsg), len);
+ *infotype = SCTP_RECVV_RCVINFO;
+ *infolen = len;
+ } else if (*infotype == SCTP_RECVV_NXTINFO) {
+ if (_infolen < len +
+ sizeof(struct sctp_nxtinfo))
+ break;
+ memcpy(info + len, info,
+ sizeof(struct sctp_nxtinfo));
+ memcpy(info, CMSG_DATA(cmsg), len);
+ *infotype = SCTP_RECVV_RN;
+ *infolen = len + sizeof(struct sctp_nxtinfo);
+ } else {
+ break;
+ }
+ } else if (cmsg->cmsg_type == SCTP_NXTINFO) {
+ len = sizeof(struct sctp_nxtinfo);
+ if (*infotype == SCTP_RECVV_NOINFO) {
+ if (_infolen < len)
+ break;
+ memcpy(info, CMSG_DATA(cmsg), len);
+ *infotype = SCTP_RECVV_NXTINFO;
+ *infolen = len;
+ } else if (*infotype == SCTP_RECVV_RCVINFO) {
+ if (_infolen < len +
+ sizeof(struct sctp_rcvinfo))
+ break;
+ memcpy(info + sizeof(struct sctp_rcvinfo),
+ CMSG_DATA(cmsg), len);
+ *infotype = SCTP_RECVV_RN;
+ *infolen = len + sizeof(struct sctp_rcvinfo);
+ } else {
+ break;
+ }
+ }
+ }
+
+ return error;
+}
+#endif
diff --git a/src/lib/sendmsg.c b/src/lib/sendmsg.c
new file mode 100644
index 0000000..4c90b07
--- /dev/null
+++ b/src/lib/sendmsg.c
@@ -0,0 +1,239 @@
+/* SCTP kernel Implementation: User API extensions.
+ *
+ * sendmsg.c
+ *
+ * Distributed under the terms of the LGPL v2.1 as described in
+ * http://www.gnu.org/copyleft/lesser.txt
+ *
+ * This file is part of the user library that offers support for the
+ * SCTP kernel Implementation. The main purpose of this
+ * code is to provide the SCTP Socket API mappings for user
+ * application to interface with the SCTP in kernel.
+ *
+ * This implementation is based on the Socket API Extensions for SCTP
+ * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
+ *
+ * Copyright (c) 2003 Intel Corp.
+ *
+ * Written or modified by:
+ * Ardelle Fan <ardelle.fan@intel.com>
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */
+#include <netinet/sctp.h>
+
+/* This library function assists the user with the advanced features
+ * of SCTP. This is a new SCTP API described in the section 8.7 of the
+ * Sockets API Extensions for SCTP. This is implemented using the
+ * sendmsg() interface.
+ */
+int
+sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to,
+ socklen_t tolen, uint32_t ppid, uint32_t flags,
+ uint16_t stream_no, uint32_t timetolive, uint32_t context)
+{
+ struct msghdr outmsg;
+ struct iovec iov;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+
+ outmsg.msg_name = to;
+ outmsg.msg_namelen = tolen;
+ outmsg.msg_iov = &iov;
+ iov.iov_base = (void *)msg;
+ iov.iov_len = len;
+ outmsg.msg_iovlen = 1;
+
+ outmsg.msg_control = outcmsg;
+ outmsg.msg_controllen = sizeof(outcmsg);
+ outmsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmsg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ outmsg.msg_controllen = cmsg->cmsg_len;
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_flags = flags;
+ sinfo->sinfo_stream = stream_no;
+ sinfo->sinfo_timetolive = timetolive;
+ sinfo->sinfo_context = context;
+
+ return sendmsg(s, &outmsg, 0);
+}
+
+/* This library function assist the user with sending a message without
+ * dealing directly with the CMSG header.
+ */
+int
+sctp_send(int s, const void *msg, size_t len,
+ const struct sctp_sndrcvinfo *sinfo, int flags)
+{
+ struct msghdr outmsg;
+ struct iovec iov;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+
+ outmsg.msg_name = NULL;
+ outmsg.msg_namelen = 0;
+ outmsg.msg_iov = &iov;
+ iov.iov_base = (void *)msg;
+ iov.iov_len = len;
+ outmsg.msg_iovlen = 1;
+ outmsg.msg_control = NULL;
+ outmsg.msg_controllen = 0;
+
+ if (sinfo) {
+ struct cmsghdr *cmsg;
+
+ outmsg.msg_control = outcmsg;
+ outmsg.msg_controllen = sizeof(outcmsg);
+ outmsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&outmsg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ outmsg.msg_controllen = cmsg->cmsg_len;
+ memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo));
+ }
+
+ return sendmsg(s, &outmsg, flags);
+}
+
+#ifdef HAVE_SCTP_SENDV
+static struct cmsghdr *sctp_sendv_store_cmsg(struct cmsghdr *cmsg, int *cmsglen,
+ int type, int len, void *data)
+{
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = type;
+ cmsg->cmsg_len = CMSG_LEN(len);
+ memcpy(CMSG_DATA(cmsg), data, len);
+
+ *cmsglen += CMSG_SPACE(len);
+
+ return (struct cmsghdr *)((char *)cmsg + CMSG_SPACE(len));
+}
+
+int sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+ struct sockaddr *addrs, int addrcnt, void *info,
+ socklen_t infolen, unsigned int infotype, int flags)
+{
+ char _cmsg[CMSG_SPACE(sizeof(struct sctp_sendv_spa))];
+ struct cmsghdr *cmsg = (struct cmsghdr *)_cmsg;
+ struct sockaddr *addr;
+ struct msghdr outmsg;
+ int len, cmsglen = 0;
+ int err, type, i;
+ char *addrbuf;
+
+ /* set msg_iov, msg_iovlen, msg_flags */
+ memset(&outmsg, 0x00, sizeof(outmsg));
+ outmsg.msg_iov = (struct iovec *)iov;
+ outmsg.msg_iovlen = iovcnt;
+ outmsg.msg_flags = flags;
+
+ /* set msg_name and msg_namelen */
+ if (addrs && addrcnt) {
+ outmsg.msg_name = addrs;
+ if (addrs->sa_family == AF_INET)
+ outmsg.msg_namelen = sizeof(struct sockaddr_in);
+ else if (addrs->sa_family == AF_INET6)
+ outmsg.msg_namelen = sizeof(struct sockaddr_in6);
+ else
+ return -EINVAL;
+ addrcnt -= 1;
+ addrbuf = (char *)addrs;
+ addrs = (struct sockaddr *)(addrbuf + outmsg.msg_namelen);
+ }
+
+ /* alloc memory only when it's multi-address */
+ if (addrcnt) {
+ len = CMSG_SPACE(sizeof(struct sockaddr_in6)) * addrcnt;
+ cmsg = malloc(sizeof(_cmsg) + len);
+ if (!cmsg)
+ return -ENOMEM;
+ }
+
+ outmsg.msg_control = cmsg;
+
+ /* add cmsg info for addr info */
+ for (i = 0, addrbuf = (char *)addrs; i < addrcnt; i++) {
+ void *ainfo;
+
+ addr = (struct sockaddr *)addrbuf;
+ if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *a = (struct sockaddr_in *)addrbuf;
+
+ len = sizeof(struct in_addr);
+ type = SCTP_DSTADDRV4;
+ ainfo = &a->sin_addr;
+ addrbuf += sizeof(*a);
+ } else if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *a = (struct sockaddr_in6 *)addrbuf;
+
+ len = sizeof(struct in6_addr);
+ type = SCTP_DSTADDRV6;
+ ainfo = &a->sin6_addr;
+ addrbuf += sizeof(*a);
+ } else {
+ free(outmsg.msg_control);
+ return -EINVAL;
+ }
+
+ cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, ainfo);
+ }
+ /* add cmsg info for addr info for snd/pr/auth info */
+ if (infotype == SCTP_SENDV_SPA) {
+ struct sctp_sendv_spa *spa = info;
+
+ if (spa->sendv_flags & SCTP_SEND_SNDINFO_VALID) {
+ type = SCTP_SNDINFO;
+ len = sizeof(struct sctp_sndinfo);
+ cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+ &spa->sendv_sndinfo);
+ }
+ if (spa->sendv_flags & SCTP_SEND_PRINFO_VALID) {
+ type = SCTP_PRINFO;
+ len = sizeof(struct sctp_prinfo);
+ cmsg = sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+ &spa->sendv_prinfo);
+ }
+ if (spa->sendv_flags & SCTP_SEND_AUTHINFO_VALID) {
+ type = SCTP_AUTHINFO;
+ len = sizeof(struct sctp_authinfo);
+ sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len,
+ &spa->sendv_authinfo);
+ }
+ } else if (infotype == SCTP_SENDV_SNDINFO) {
+ type = SCTP_SNDINFO;
+ len = sizeof(struct sctp_sndinfo);
+ sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+ } else if (infotype == SCTP_SENDV_PRINFO) {
+ type = SCTP_PRINFO;
+ len = sizeof(struct sctp_prinfo);
+ sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+ } else if (infotype == SCTP_SENDV_AUTHINFO) {
+ type = SCTP_AUTHINFO;
+ len = sizeof(struct sctp_authinfo);
+ sctp_sendv_store_cmsg(cmsg, &cmsglen, type, len, info);
+ }
+
+ outmsg.msg_controllen = cmsglen;
+
+ err = sendmsg(s, &outmsg, 0);
+
+ if (outmsg.msg_control != _cmsg)
+ free(outmsg.msg_control);
+
+ return err;
+}
+#endif
diff --git a/src/testlib/Makefile.am b/src/testlib/Makefile.am
new file mode 100644
index 0000000..b949611
--- /dev/null
+++ b/src/testlib/Makefile.am
@@ -0,0 +1,12 @@
+# Include these two in all the Makefile.am's!!!
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.rules
+
+include $(top_srcdir)/Makefile.dirs
+
+# General compilation flags
+AM_CPPFLAGS = -I$(top_builddir)/src/include
+
+noinst_LTLIBRARIES = libsctputil.la
+libsctputil_la_SOURCES = sctputil.c sctputil.h
+libsctputil_la_LDFLAGS =
diff --git a/src/testlib/sctputil.c b/src/testlib/sctputil.c
new file mode 100644
index 0000000..24f305a
--- /dev/null
+++ b/src/testlib/sctputil.c
@@ -0,0 +1,417 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (C) 1999 Cisco
+ * Copyright (C) 1999-2000 Motorola
+ # Copyright (C) 2001 Nokia
+ * Copyright (C) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Narasimha Budihal <narsi@refcode.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <malloc.h>
+#include <netinet/sctp.h>
+#include <sctputil.h>
+
+/* This function prints the cmsg data. */
+void
+test_print_cmsg(sctp_cmsg_t type, sctp_cmsg_data_t *data)
+{
+ switch(type) {
+ case SCTP_INIT:
+ printf("INIT\n");
+ printf(" sinit_num_ostreams %d\n",
+ data->init.sinit_num_ostreams);
+ printf(" sinit_max_instreams %d\n",
+ data->init.sinit_max_instreams);
+ printf(" sinit_max_attempts %d\n",
+ data->init.sinit_max_attempts);
+ printf(" sinit_max_init_timeo %d\n",
+ data->init.sinit_max_init_timeo);
+
+ break;
+ case SCTP_SNDRCV:
+ printf("SNDRCV\n");
+ printf(" sinfo_stream %u\n", data->sndrcv.sinfo_stream);
+ printf(" sinfo_ssn %u\n", data->sndrcv.sinfo_ssn);
+ printf(" sinfo_flags 0x%x\n", data->sndrcv.sinfo_flags);
+ printf(" sinfo_ppid %u\n", data->sndrcv.sinfo_ppid);
+ printf(" sinfo_context %x\n", data->sndrcv.sinfo_context);
+ printf(" sinfo_tsn %u\n", data->sndrcv.sinfo_tsn);
+ printf(" sinfo_cumtsn %u\n", data->sndrcv.sinfo_cumtsn);
+ printf(" sinfo_assoc_id %u\n", data->sndrcv.sinfo_assoc_id);
+
+ break;
+
+ default:
+ printf("UNKNOWN CMSG: %d\n", type);
+ break;
+ }
+}
+
+/* This function prints the message. */
+void
+test_print_message(int sk, struct msghdr *msg, size_t msg_len)
+{
+ sctp_cmsg_data_t *data;
+ struct cmsghdr *cmsg;
+ int i;
+ int done = 0;
+ char save;
+ union sctp_notification *sn;
+
+ for (cmsg = CMSG_FIRSTHDR(msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ data = (sctp_cmsg_data_t *)CMSG_DATA(cmsg);
+ test_print_cmsg(cmsg->cmsg_type, data);
+ }
+
+ if (!(MSG_NOTIFICATION & msg->msg_flags)) {
+ int index = 0;
+ /* Make sure that everything is printable and that we
+ * are NUL terminated...
+ */
+ printf("DATA(%lu): ", msg_len);
+ while ( msg_len > 0 ) {
+ char *text;
+ int len;
+
+ text = msg->msg_iov[index].iov_base;
+ len = msg->msg_iov[index].iov_len;
+
+ save = text[msg_len-1];
+ if ( len > msg_len ) {
+ text[(len = msg_len) - 1] = '\0';
+ }
+
+ if ( (msg_len -= len) > 0 ) { index++; }
+
+ for (i = 0; i < len - 1; ++i) {
+ if (!isprint(text[i])) text[i] = '.';
+ }
+
+ printf("%s", text);
+ text[msg_len-1] = save;
+
+ if ( (done = !strcmp(text, "exit")) ) { break; }
+ }
+ } else {
+ printf("NOTIFICATION: ");
+ sn = (union sctp_notification *)msg->msg_iov[0].iov_base;
+ switch (sn->sn_header.sn_type) {
+ case SCTP_ASSOC_CHANGE:
+ switch (sn->sn_assoc_change.sac_state) {
+ case SCTP_COMM_UP:
+ printf("ASSOC_CHANGE - COMM_UP");
+ break;
+ case SCTP_COMM_LOST:
+ printf("ASSOC_CHANGE - COMM_LOST");
+ break;
+ case SCTP_RESTART:
+ printf("ASSOC_CHANGE - RESTART");
+ break;
+ case SCTP_SHUTDOWN_COMP:
+ printf("ASSOC_CHANGE - SHUTDOWN_COMP");
+ break;
+ case SCTP_CANT_STR_ASSOC:
+ printf("ASSOC_CHANGE - CANT_STR_ASSOC");
+ break;
+ default:
+ printf("ASSOC_CHANGE - UNEXPECTED(%d)",
+ sn->sn_assoc_change.sac_state);
+ break;
+ }
+ break;
+ default:
+ printf("%d", sn->sn_header.sn_type);
+ break;
+ }
+ }
+
+ printf("\n");
+}
+
+/* Check if a buf/msg_flags matches a notification, its type, and possibly an
+ * additional field in the corresponding notification structure.
+ */
+void
+test_check_buf_notification(void *buf, int datalen, int msg_flags,
+ int expected_datalen, uint16_t expected_sn_type,
+ uint32_t expected_additional)
+{
+ union sctp_notification *sn;
+
+ if (!(msg_flags & MSG_NOTIFICATION))
+ tst_brkm(TBROK, tst_exit, "Got a datamsg, expecting "
+ "notification");
+
+ if (expected_datalen <= 0)
+ return;
+
+ if (datalen != expected_datalen)
+ tst_brkm(TBROK, tst_exit, "Got a notification of unexpected "
+ "length:%d, expected length:%d", datalen,
+ expected_datalen);
+
+ sn = (union sctp_notification *)buf;
+ if (sn->sn_header.sn_type != expected_sn_type)
+ tst_brkm(TBROK, tst_exit, "Unexpected notification:%d"
+ "expected:%d", sn->sn_header.sn_type,
+ expected_sn_type);
+
+ switch(sn->sn_header.sn_type){
+ case SCTP_ASSOC_CHANGE:
+ if (sn->sn_assoc_change.sac_state != expected_additional)
+ tst_brkm(TBROK, tst_exit, "Unexpected sac_state:%d "
+ "expected:%d", sn->sn_assoc_change.sac_state,
+ expected_additional);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Check if a message matches a notification, its type, and possibly an
+ * additional field in the corresponding notification structure.
+ */
+void
+test_check_msg_notification(struct msghdr *msg, int datalen,
+ int expected_datalen, uint16_t expected_sn_type,
+ uint32_t expected_additional)
+{
+ test_check_buf_notification(msg->msg_iov[0].iov_base, datalen,
+ msg->msg_flags, expected_datalen,
+ expected_sn_type, expected_additional);
+}
+
+/* Check if a buf/msg_flags/sinfo corresponds to data, its length, msg_flags,
+ * stream and ppid.
+ */
+void
+test_check_buf_data(void *buf, int datalen, int msg_flags,
+ struct sctp_sndrcvinfo *sinfo, int expected_datalen,
+ int expected_msg_flags, uint16_t expected_stream,
+ uint32_t expected_ppid)
+{
+ if (msg_flags & MSG_NOTIFICATION)
+ tst_brkm(TBROK, tst_exit, "Got a notification, expecting a"
+ "datamsg");
+
+ if (expected_datalen <= 0)
+ return;
+
+ if (datalen != expected_datalen)
+ tst_brkm(TBROK, tst_exit, "Got a datamsg of unexpected "
+ "length:%d, expected length:%d", datalen,
+ expected_datalen);
+
+ if ((msg_flags & ~0x80000000) != expected_msg_flags)
+ tst_brkm(TBROK, tst_exit, "Unexpected msg_flags:0x%x "
+ "expecting:0x%x", msg_flags, expected_msg_flags);
+
+ if ((0 == expected_stream) && (0 == expected_ppid))
+ return;
+
+ if (!sinfo)
+ tst_brkm(TBROK, tst_exit, "Null sinfo, but expected "
+ "stream:%d expected ppid:%d", expected_stream,
+ expected_ppid);
+
+ if (sinfo->sinfo_stream != expected_stream)
+ tst_brkm(TBROK, tst_exit, "stream mismatch: expected:%x "
+ "got:%x", expected_stream, sinfo->sinfo_stream);
+ if (sinfo->sinfo_ppid != expected_ppid)
+ tst_brkm(TBROK, tst_exit, "ppid mismatch: expected:%x "
+ "got:%x\n", expected_ppid, sinfo->sinfo_ppid);
+}
+
+/* Check if a message corresponds to data, its length, msg_flags, stream and
+ * ppid.
+ */
+void
+test_check_msg_data(struct msghdr *msg, int datalen, int expected_datalen,
+ int expected_msg_flags, uint16_t expected_stream,
+ uint32_t expected_ppid)
+{
+ struct cmsghdr *cmsg = NULL;
+ struct sctp_sndrcvinfo *sinfo = NULL;
+
+ /* Receive auxiliary data in msgh. */
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg)){
+ if (IPPROTO_SCTP == cmsg->cmsg_level &&
+ SCTP_SNDRCV == cmsg->cmsg_type)
+ break;
+ } /* for( all cmsgs) */
+
+ if ((!cmsg) ||
+ (cmsg->cmsg_len < CMSG_LEN(sizeof(struct sctp_sndrcvinfo))))
+ sinfo = NULL;
+ else
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+
+ test_check_buf_data(msg->msg_iov[0].iov_base, datalen, msg->msg_flags,
+ sinfo, expected_datalen, expected_msg_flags,
+ expected_stream, expected_ppid);
+
+}
+
+
+/* Allocate a buffer of requested len and fill in with data. */
+void *
+test_build_msg(int len)
+{
+ int i = len - 1;
+ int n;
+ unsigned char msg[] =
+ "012345678901234567890123456789012345678901234567890";
+ char *msg_buf, *p;
+
+ msg_buf = (char *)malloc(len);
+ if (!msg_buf)
+ tst_brkm(TBROK, tst_exit, "malloc failed");
+
+ p = msg_buf;
+
+ do {
+ n = ((i > 50)?50:i);
+ memcpy(p, msg, ((i > 50)?50:i));
+ p += n;
+ i -= n;
+ } while (i > 0);
+
+ msg_buf[len-1] = '\0';
+
+ return(msg_buf);
+}
+
+/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
+void test_enable_assoc_change(int fd)
+{
+ struct sctp_event_subscribe subscribe;
+
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ test_setsockopt(fd, SCTP_EVENTS, (char *)&subscribe,
+ sizeof(subscribe));
+}
+
+static int cmp_addr(sockaddr_storage_t *addr1, sockaddr_storage_t *addr2)
+{
+ if (addr1->sa.sa_family != addr2->sa.sa_family)
+ return 0;
+ switch (addr1->sa.sa_family) {
+ case AF_INET6:
+ if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+ return -1;
+ return memcmp(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr,
+ sizeof(addr1->v6.sin6_addr));
+ case AF_INET:
+ if (addr1->v4.sin_port != addr2->v4.sin_port)
+ return 0;
+ return memcmp(&addr1->v4.sin_addr, &addr2->v4.sin_addr,
+ sizeof(addr1->v4.sin_addr));
+ default:
+ tst_brkm(TBROK, tst_exit, "invalid address type %d",
+ addr1->sa.sa_family);
+ return -1;
+ }
+}
+
+/* Test peer addresses for association. */
+int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count)
+{
+ struct sockaddr *addrs;
+ int error, i, j;
+ struct sockaddr *sa_addr;
+ socklen_t addrs_size = 0;
+ void *addrbuf;
+ char *found = (char *) malloc(count);
+ memset(found, 0, count);
+
+ error = sctp_getpaddrs(sk, asoc, &addrs);
+ if (-1 == error) {
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno));
+ return error;
+ }
+ if (error != count) {
+ sctp_freepaddrs(addrs);
+ tst_brkm(TBROK, tst_exit, "peer count %d mismatch, expected %d",
+ error, count);
+ }
+ addrbuf = addrs;
+ for (i = 0; i < count; i++) {
+ sa_addr = (struct sockaddr *)addrbuf;
+ switch (sa_addr->sa_family) {
+ case AF_INET:
+ addrs_size += sizeof(struct sockaddr_in);
+ addrbuf += sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ addrs_size += sizeof(struct sockaddr_in6);
+ addrbuf += sizeof(struct sockaddr_in6);
+ break;
+ default:
+ errno = EINVAL;
+ sctp_freepaddrs(addrs);
+ tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s", strerror(errno));
+ return -1;
+ }
+ for (j = 0; j < count; j++) {
+ if (cmp_addr((sockaddr_storage_t *)sa_addr,
+ &peers[j]) == 0) {
+ found[j] = 1;
+ }
+ }
+ }
+ for (j = 0; j < count; j++) {
+ if (found[j] == 0) {
+ tst_brkm(TBROK, tst_exit, "peer address %d not found", j);
+ }
+ }
+ sctp_freepaddrs(addrs);
+ free(found);
+ return 0;
+}
diff --git a/src/testlib/sctputil.h b/src/testlib/sctputil.h
new file mode 100644
index 0000000..9dbabd4
--- /dev/null
+++ b/src/testlib/sctputil.h
@@ -0,0 +1,358 @@
+/* SCTP kernel Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Nokia, Inc.
+ * Copyright (c) 2001 La Monte H.P. Yarroll
+ *
+ * The SCTP implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Any bugs reported to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ *
+ * Written or modified by:
+ * La Monte H.P. Yarroll <piggy@acm.org>
+ * Karl Knutson <karl@athena.chicago.il.us>
+ * Randall Stewart <randall@stewart.chicago.il.us>
+ * Ken Morneau <kmorneau@cisco.com>
+ * Qiaobing Xie <qxie1@motorola.com>
+ * Daisy Chang <daisyc@us.ibm.com>
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <samudrala@us.ibm.com>
+ * Hui Huang <hui.huang@nokia.com>
+ */
+
+#ifndef __sctputil_h__
+#define __sctputil_h__
+
+#ifdef LTP
+#include <test.h>
+#include <usctest.h>
+#endif
+
+#include <string.h>
+
+typedef union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ struct sockaddr sa;
+} sockaddr_storage_t;
+
+
+#define REALLY_BIG 65536
+
+/* Literal defines. */
+#ifdef PROT_SOCK
+#define SCTP_TESTPORT_1 PROT_SOCK
+#else
+#define SCTP_TESTPORT_1 1024
+#endif
+#define SCTP_TESTPORT_2 (SCTP_TESTPORT_1+1)
+
+#define SCTP_IP_BCAST htonl(0xffffffff)
+#define SCTP_IP_LOOPBACK htonl(0x7f000001)
+
+/* These are stolen from <netinet/in.h>. */
+#define SCTP_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define SCTP_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+/* Display an IPv4 address in readable format. */
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+/* Display an IPv6 address in readable format. */
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+
+#define DUMP_CORE { \
+ char *diediedie = 0; \
+ printf("DUMP_CORE %s: %d\n", __FILE__, __LINE__);\
+ *diediedie = 0; \
+}
+
+#ifndef LTP
+enum {
+ TPASS,
+ TINFO,
+};
+
+extern char *TCID;
+extern int TST_TOTAL;
+extern int TST_CNT;
+
+#define tst_brkm(a1, a2, whatever...) \
+ { \
+ printf("%s %2d BROK : ", TCID, ++TST_CNT); \
+ printf(whatever); \
+ printf("\n"); \
+ DUMP_CORE \
+ }
+#define tst_resm(a1, whatever...) \
+ { \
+ printf("%s %2d %s : ", TCID, \
+ (a1 == TPASS)?++TST_CNT:0, \
+ (a1 == TPASS)?"PASS":"INFO"); \
+ printf(whatever); \
+ printf("\n"); \
+ }
+#endif
+
+static inline int test_socket(int domain, int type, int protocol)
+{
+ int sk = socket(domain, type, protocol);
+ if (-1 == sk)
+ tst_brkm(TBROK, tst_exit, "socket: %s", strerror(errno));
+ return sk;
+}
+
+static inline int test_bind(int sk, struct sockaddr *addr, socklen_t addrlen)
+{
+ int error = bind(sk, addr, addrlen);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "bind: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_bindx_add(int sk, struct sockaddr *addr, int count)
+{
+ int error = sctp_bindx(sk, addr, count, SCTP_BINDX_ADD_ADDR);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "bindx (add): %s", strerror(errno));
+ return error;
+}
+
+static inline int test_listen(int sk, int backlog)
+{
+ int error = listen(sk, backlog);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "listen: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_connect(int sk, struct sockaddr *addr, socklen_t addrlen)
+{
+ int error = connect(sk, addr, addrlen);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "connect: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_connectx(int sk, struct sockaddr *addr, int count)
+{
+ int error = sctp_connectx(sk, addr, count, NULL);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "connectx: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_accept(int sk, struct sockaddr *addr, socklen_t *addrlen)
+{
+ int error = accept(sk, addr, addrlen);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "accept: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_send(int sk, const void *msg, size_t len, int flags)
+{
+ int error = send(sk, msg, len, flags);
+ if (len != error)
+ tst_brkm(TBROK, tst_exit, "send: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+
+static inline int test_sendto(int sk, const void *msg, size_t len, int flags,
+ const struct sockaddr *to, socklen_t tolen)
+{
+ int error = sendto(sk, msg, len, flags, to, tolen);
+ if (len != error)
+ tst_brkm(TBROK, tst_exit, "sendto: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+
+static inline int test_sendmsg(int sk, const struct msghdr *msg, int flags,
+ int msglen)
+{
+ int error = sendmsg(sk, msg, flags);
+ if (msglen != error)
+ tst_brkm(TBROK, tst_exit, "sendmsg: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+
+static inline int test_recv(int sk, void *buf, size_t len, int flags)
+{
+ int error = recv(sk, buf, len, flags);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "recv: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_recvmsg(int sk, struct msghdr *msg, int flags)
+{
+ int error = recvmsg(sk, msg, flags);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "recvmsg: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_shutdown(int sk, int how)
+{
+ int error = shutdown(sk, how);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "shutdown: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_getsockopt(int sk, int optname, void *optval,
+ socklen_t *optlen)
+{
+ int error = getsockopt(sk, SOL_SCTP, optname, optval, optlen);
+ if (error)
+ tst_brkm(TBROK, tst_exit, "getsockopt(%d): %s", optname,
+ strerror(errno));
+ return error;
+}
+
+static inline int test_setsockopt(int sk, int optname, const void *optval,
+ socklen_t optlen)
+{
+ int error = setsockopt(sk, SOL_SCTP, optname, optval, optlen);
+ if (error)
+ tst_brkm(TBROK, tst_exit, "setsockopt(%d): %s", optname,
+ strerror(errno));
+ return error;
+}
+
+static inline int test_sctp_peeloff(int sk, sctp_assoc_t assoc_id)
+{
+ int error = sctp_peeloff(sk, assoc_id);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "sctp_peeloff: %s", strerror(errno));
+ return error;
+}
+
+static inline int test_sctp_sendmsg(int s, const void *msg, size_t len,
+ struct sockaddr *to, socklen_t tolen,
+ uint32_t ppid, uint32_t flags,
+ uint16_t stream_no, uint32_t timetolive,
+ uint32_t context)
+{
+ int error = sctp_sendmsg(s, msg, len, to, tolen, ppid, flags, stream_no,
+ timetolive, context);
+ if (len != error)
+ tst_brkm(TBROK, tst_exit, "sctp_sendmsg: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+
+static inline int test_sctp_send(int s, const void *msg, size_t len,
+ const struct sctp_sndrcvinfo *sinfo,
+ int flags)
+{
+ int error = sctp_send(s, msg, len, sinfo, flags);
+ if (len != error)
+ tst_brkm(TBROK, tst_exit, "sctp_send: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+
+#ifdef HAVE_SCTP_SENDV
+static inline int test_sctp_sendv(int s, const struct iovec *iov, int iovcnt,
+ struct sockaddr *addrs, int addrcnt,
+ void *info, socklen_t infolen,
+ unsigned int infotype, int flags)
+{
+ int error = sctp_sendv(s, iov, iovcnt, addrs, addrcnt, info, infolen,
+ infotype, flags);
+ int i, tlen = 0;
+
+ for (i = 0; i < iovcnt; i++)
+ tlen += iov->iov_len;
+
+ if (tlen != error)
+ tst_brkm(TBROK, tst_exit, "sctp_sendv: error:%d errno:%d",
+ error, errno);
+ return error;
+}
+#endif
+
+static inline int test_sctp_recvmsg(int sk, void *msg, size_t len,
+ struct sockaddr *from, socklen_t *fromlen,
+ struct sctp_sndrcvinfo *sinfo,
+ int *msg_flags)
+{
+ int error = sctp_recvmsg(sk, msg, len, from, fromlen, sinfo, msg_flags);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno));
+ return error;
+}
+
+#ifdef HAVE_SCTP_SENDV
+static inline int test_sctp_recvv(int s, const struct iovec *iov, int iovlen,
+ struct sockaddr *from, socklen_t *fromlen,
+ void *info, socklen_t *infolen,
+ unsigned int *infotype, int *flags)
+{
+ int error = sctp_recvv(s, iov, iovlen, from, fromlen, info, infolen,
+ infotype, flags);
+ if (-1 == error)
+ tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno));
+ return error;
+}
+#endif
+
+static inline void *test_malloc(size_t size)
+{
+ void *buf = malloc(size);
+ if (NULL == buf)
+ tst_brkm(TBROK, tst_exit, "malloc failed");
+ return buf;
+}
+
+void test_check_msg_notification(struct msghdr *, int, int, uint16_t, uint32_t);
+void test_check_buf_notification(void *, int, int, int, uint16_t, uint32_t);
+void test_check_msg_data(struct msghdr *, int, int, int, uint16_t, uint32_t);
+void test_check_buf_data(void *, int, int, struct sctp_sndrcvinfo *, int, int,
+ uint16_t, uint32_t);
+void *test_build_msg(int);
+void test_enable_assoc_change(int);
+void test_print_message(int sk, struct msghdr *msg, size_t msg_len);
+int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count);
+
+#endif /* __sctputil_h__ */
diff --git a/src/withsctp/.gitignore b/src/withsctp/.gitignore
new file mode 100644
index 0000000..498e578
--- /dev/null
+++ b/src/withsctp/.gitignore
@@ -0,0 +1,2 @@
+checksctp
+withsctp
diff --git a/src/withsctp/Makefile.am b/src/withsctp/Makefile.am
new file mode 100644
index 0000000..3157588
--- /dev/null
+++ b/src/withsctp/Makefile.am
@@ -0,0 +1,28 @@
+# -*- Makefile -*-
+#
+# The author (La Monte H.P. Yarroll) disclaims copyright on this file.
+#
+
+include $(top_srcdir)/Makefile.vars
+include $(top_srcdir)/Makefile.dirs
+include $(top_srcdir)/Makefile.rules
+
+bin_PROGRAMS = checksctp
+bin_SCRIPTS = withsctp
+
+AM_CPPFLAGS=-I$(top_builddir)/src/include
+pkglib_LTLIBRARIES = libwithsctp.la
+libwithsctp_la_SOURCES = sctp_load_libs.c sctp_socket.c sctp_bind.c \
+ sctp_sockopt.c sctp_socket.h
+libwithsctp_la_LDFLAGS = -version-info \
+ @LIBWITHSCTP_CURRENT@:@LIBWITHSCTP_REVISION@:@LIBWITHSCTP_AGE@ -ldl
+
+pkgdoc_DATA = sctp_load_libs.c sctp_socket.c sctp_bind.c \
+ sctp_sockopt.c sctp_socket.h checksctp.c
+
+withsctp: withsctp.in
+ $(edit) $< >$@
+
+EXTRA_DIST += withsctp.in
+
+CLEANFILES += withsctp
diff --git a/src/withsctp/README b/src/withsctp/README
new file mode 100644
index 0000000..c7d8b97
--- /dev/null
+++ b/src/withsctp/README
@@ -0,0 +1,15 @@
+This is a package to let you use SCTP with your existing TCP-based binaries.
+
+usage:
+
+$ withsctp xinetd # Start xinetd stream services on SCTP.
+$ withsctp telnet localhost # Make a telnet over SCTP/IP connection.
+
+To install, edit the top of Makefile to set your install path(s) and then
+
+$ make all
+# make install
+
+This package originally written by La Monte H.P. Yarroll <piggy@acm.org>.
+To submit fixes or bug reports see lksctp.sourceforget.net.
+You can try the author or lksctp-developers@lists.sourceforget.net for support.
diff --git a/src/withsctp/checksctp.c b/src/withsctp/checksctp.c
new file mode 100644
index 0000000..bda9c1d
--- /dev/null
+++ b/src/withsctp/checksctp.c
@@ -0,0 +1,58 @@
+/* Does this host have SCTP?
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int main(void)
+{
+ int fd;
+
+ fd = socket(PF_INET, SOCK_STREAM, SHOULD_IPPROTO_SCTP);
+
+ if (fd <= 0) {
+ perror("checksctp");
+ exit(1);
+ } else {
+ fprintf(stderr, "SCTP supported\n");
+ }
+
+ close(fd);
+ return 0;
+}
diff --git a/src/withsctp/notes.txt b/src/withsctp/notes.txt
new file mode 100644
index 0000000..ef532ec
--- /dev/null
+++ b/src/withsctp/notes.txt
@@ -0,0 +1,6 @@
+Fri Dec 26 16:20:36 EST 2003
+
+It would be nice for withsctp to provide more facilities.
+
+Perhaps we could capture the bind call and allow substitution such as the
+arguments to sctp_darn.
diff --git a/src/withsctp/sctp_bind.c b/src/withsctp/sctp_bind.c
new file mode 100644
index 0000000..e744273
--- /dev/null
+++ b/src/withsctp/sctp_bind.c
@@ -0,0 +1,58 @@
+/* Wrap bind() to force the protocol for STREAM connections to SCTP.
+ *
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old bind().
+ *
+ * gcc sctp_socket.c sctp_bind.c -o sctp_socket.so -ldl -shared -O2 -s
+ * export LD_PRELOAD=./sctp_socket.so
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int
+bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
+{
+ _sctp_load_libs();
+
+ /* STUB. The intent is to allow us to substitute an elaborate call to
+ * bindx() for the initial call to bind(). TBD.
+ */
+
+ return (real_bind)(sockfd, my_addr, addrlen);
+}
diff --git a/src/withsctp/sctp_load_libs.c b/src/withsctp/sctp_load_libs.c
new file mode 100644
index 0000000..d6a521f
--- /dev/null
+++ b/src/withsctp/sctp_load_libs.c
@@ -0,0 +1,67 @@
+/* Load the real underlying functions for withsctp and related scripts.
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "sctp_socket.h"
+
+int (*real_bind)(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
+int (*real_socket)(int domain, int type, int protocol);
+int (*real_setsockopt)(int s, int level, int optname, const void *optval,
+ socklen_t optlen);
+static void *lib_handle = NULL;
+
+void
+_sctp_load_libs(void)
+{
+ if (NULL != lib_handle) return; /* Only init once. */
+
+ if (!(lib_handle = dlopen("libc.so", RTLD_LAZY))) {
+ if (!(lib_handle = dlopen("libc.so.6", RTLD_LAZY))) {
+ fprintf(stderr, "error loading libc!\n");
+ exit (1);
+ }
+ }
+
+ if (!(real_socket = dlsym(lib_handle, "socket"))) {
+ fprintf(stderr, "socket() not found in libc!\n");
+ exit (1);
+ }
+
+ if (!(real_bind = dlsym(lib_handle, "bind"))) {
+ fprintf(stderr, "bind() not found in libc!\n");
+ exit (1);
+ }
+
+ if (!(real_setsockopt = dlsym(lib_handle, "setsockopt"))) {
+ fprintf(stderr, "setsockopt() not found in libc!\n");
+ exit (1);
+ }
+}
diff --git a/src/withsctp/sctp_socket.c b/src/withsctp/sctp_socket.c
new file mode 100644
index 0000000..37d73af
--- /dev/null
+++ b/src/withsctp/sctp_socket.c
@@ -0,0 +1,59 @@
+/* Wrap socket() to force the protocol to SCTP for STREAM connections.
+ *
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old socket().
+ *
+ * gcc sctp_socket.c -o sctp_socket.so -ldl -shared -O2 -s
+ * export LD_PRELOAD=./sctp_socket.so
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int
+socket(int domain, int type, int protocol)
+{
+ _sctp_load_libs();
+
+ if (((PF_INET == domain) || (PF_INET6 == domain))
+ && (SOCK_STREAM == type)) {
+ protocol = SHOULD_IPPROTO_SCTP;
+ }
+
+ return (real_socket)(domain, type, protocol);
+}
diff --git a/src/withsctp/sctp_socket.h b/src/withsctp/sctp_socket.h
new file mode 100644
index 0000000..44c8226
--- /dev/null
+++ b/src/withsctp/sctp_socket.h
@@ -0,0 +1,69 @@
+/* Preprocessor definitions for withsctp and supporting scripts.
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <dlfcn.h> /* for dlopen() and company */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <netinet/tcp.h>
+
+extern int (*real_bind)(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
+extern int (*real_socket)(int domain, int type, int protocol);
+extern int (*real_setsockopt)(int s, int level, int optname, const void *optval,
+ socklen_t optlen);
+extern void _sctp_load_libs(void);
diff --git a/src/withsctp/sctp_sockopt.c b/src/withsctp/sctp_sockopt.c
new file mode 100644
index 0000000..01b8308
--- /dev/null
+++ b/src/withsctp/sctp_sockopt.c
@@ -0,0 +1,56 @@
+/* Wrap socket() to force the protocol to SCTP for STREAM connections.
+ *
+ * Thanks to Midgard Security Services for
+ * http://www.securiteam.com/tools/3D5PTR5QAE.html
+ * from whence I cribbed the code to find the old socket().
+ *
+ * Copyright 2003 La Monte HP Yarroll <piggy@acm.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with
+ * the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h> /* for strncmp() */
+#include <stdio.h>
+#include "sctp_socket.h"
+
+/* IPPROTO_SCTP SHOULD be defined in
+ * /usr/include/linux/in.h but probably isn't.
+ * It is an enum element, not a #define, so we can't easily check.
+ */
+#define SHOULD_IPPROTO_SCTP 132
+
+int
+setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+ _sctp_load_libs();
+
+ if ((IPPROTO_TCP == level) && (TCP_NODELAY == optname)) {
+ level = SHOULD_IPPROTO_SCTP;
+ optname = SCTP_NODELAY;
+ }
+
+ return (real_setsockopt)(s, level, optname, optval, optlen);
+}
diff --git a/src/withsctp/withsctp.in b/src/withsctp/withsctp.in
new file mode 100644
index 0000000..ef4f7bb
--- /dev/null
+++ b/src/withsctp/withsctp.in
@@ -0,0 +1,13 @@
+#!/bin/sh
+# -*- sh -*-
+LIBDIR=@libdir@/@PACKAGE@
+BINDIR=@bindir@
+LIBVER=@LIBWITHSCTP_CURRENT@.@LIBWITHSCTP_AGE@.@LIBWITHSCTP_REVISION@
+export LD_PRELOAD=${LIBDIR}/libwithsctp.so.${LIBVER}
+if ! ${BINDIR}/checksctp 2> /dev/null
+then
+ ${BINDIR}/checksctp;
+ exit 1;
+fi
+
+exec "$@"
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/stamp-h.in
@@ -0,0 +1 @@
+timestamp