Unbreak (partially) SCTP on Solaris.

Solaris implements an (older?) version of the API for SCTP_MAXSEG,
which takes an integer argument rather than a struct sctp_assoc_val.
We need to test for that and handle it appropriately.  There are some
signs it doesn't even work correctly if we do this, so quietly ignore
errors that happen if the OS complains it's unsupported.

Also, Solaris doesn't support SCTP_DISABLE_FRAGMENTS even though it
defines the preprocessor symbol for this.  Rather than aborting when
we try to unsuccessfully unset this option, just ignore the error.

Lightly tested with SCTP over IPv6 on localhost.
This commit is contained in:
Bruce A. Mah 2015-01-06 10:22:00 -08:00
parent 4874c4a88b
commit 3b60f09017
2 changed files with 40 additions and 2 deletions

View File

@ -25,6 +25,7 @@
# Initialize the autoconf system for the specified tool, version and mailing list
AC_INIT(iperf, 3-CURRENT, https://github.com/esnet/iperf, iperf, http://software.es.net/iperf/)
AC_LANG(C)
# Specify where the auxiliary files created by configure should go. The config
# directory is picked so that they don't clutter up more useful directories.
@ -88,6 +89,7 @@ AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([netinet/sctp.h],
AC_DEFINE([HAVE_SCTP], [1], [Have SCTP support.])
AC_SEARCH_LIBS(sctp_bindx, [sctp]),
AC_CHECK_TYPES([struct sctp_assoc_value])
[],
[#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>

View File

@ -1,5 +1,5 @@
/*
* iperf, Copyright (c) 2014, The Regents of the University of
* iperf, Copyright (c) 2014, 2015, The Regents of the University of
* California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved.
@ -280,8 +280,21 @@ iperf_sctp_connect(struct iperf_test *test)
}
if ((test->settings->mss >= 512 && test->settings->mss <= 131072)) {
/*
* Some platforms use a struct sctp_assoc_value as the
* argument to SCTP_MAXSEG. Other (older API implementations)
* take an int. FreeBSD 10 and CentOS 6 support SCTP_MAXSEG,
* but OpenSolaris 11 doesn't.
*/
#ifdef HAVE_STRUCT_SCTP_ASSOC_VALUE
struct sctp_assoc_value av;
/*
* Some platforms support SCTP_FUTURE_ASSOC, others need to
* (equivalently) do 0 here. FreeBSD 10 is an example of the
* former, CentOS 6 Linux is an example of the latter.
*/
#ifdef SCTP_FUTURE_ASSOC
av.assoc_id = SCTP_FUTURE_ASSOC;
#else
@ -295,6 +308,21 @@ iperf_sctp_connect(struct iperf_test *test)
i_errno = IESETMSS;
return -1;
}
#else
opt = test->settings->mss;
/*
* Solaris might not support this option. If it doesn't work,
* ignore the error (at least for now).
*/
if (setsockopt(s, IPPROTO_SCTP, SCTP_MAXSEG, &opt, sizeof(opt)) < 0 &&
errno != ENOPROTOOPT) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETMSS;
return -1;
}
#endif HAVE_STRUCT_SCTP_ASSOC_VALUE
}
if (test->settings->num_ostreams > 0) {
@ -333,8 +361,16 @@ iperf_sctp_connect(struct iperf_test *test)
return -1;
}
/*
* We want to allow fragmentation. But there's at least one
* implementation (Solaris) that doesn't support this option,
* even though it defines SCTP_DISABLE_FRAGMENTS. So we have to
* try setting the option and ignore the error, if it doesn't
* work.
*/
opt = 0;
if(setsockopt(s, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &opt, sizeof(opt)) < 0) {
if (setsockopt(s, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &opt, sizeof(opt)) < 0 &&
errno != ENOPROTOOPT) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETSCTPDISABLEFRAG;