Fix SCTP support on FreeBSD & NetBSD

Unlike Linux, Solaris, and Illumos (and probably others), the 2 BSDs that still
support SCTP didn't put SCTP into its own library, they put it into libc.

They, unlike Linux, don't set SOL_SCTP for us. The official method appears to
be calling getprotobyname("sctp") & endprotoent(), with getprotobyname()
returning a struct that has a p_proto entry. This all reads from
/etc/protocols. However, SCTP is assigned 132 by IANA, so it's 132 everywhere,
so I just set SOL_SCTP to 132 if it's not already set.
This commit is contained in:
jailbird777 2022-08-15 19:03:49 -05:00 committed by Doug Freed
parent b951e21b5d
commit 1b64bfa05e
3 changed files with 19 additions and 11 deletions

View file

@ -335,9 +335,8 @@ AC_HELP_STRING([--disable-sctp],[Disable SCTP support]),
if test "$sctp" = yes; then if test "$sctp" = yes; then
AC_CHECK_HEADER(netinet/sctp.h, [ AC_CHECK_HEADER(netinet/sctp.h, [
AC_CHECK_LIB(sctp, sctp_bindx, AC_SEARCH_LIBS(sctp_bindx, sctp,
[ [
AC_SUBST(LIBSCTP_LD, -lsctp)
AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.]) AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.])
], sctp=no) ], sctp=no)
], sctp=no) ], sctp=no)

View file

@ -84,7 +84,7 @@ AC_TYPE_UID_T
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([crypt.h unistd.h sys/socket.h sys/stat.h sys/time.h time.h netinet/in.h netinet/tcp.h netinet/sctp.h arpa/inet.h errno.h sys/uio.h spawn.h sys/poll.h sys/epoll.h sys/select.h sys/devpoll.h sys/event.h port.h signal.h sys/signalfd.h sys/timerfd.h]) AC_CHECK_HEADERS([crypt.h unistd.h sys/socket.h sys/stat.h sys/time.h time.h netinet/in.h netinet/tcp.h arpa/inet.h errno.h sys/uio.h spawn.h sys/poll.h sys/epoll.h sys/select.h sys/devpoll.h sys/event.h port.h signal.h sys/signalfd.h sys/timerfd.h])
AC_HEADER_TIME AC_HEADER_TIME
dnl Networking Functions dnl Networking Functions
@ -371,13 +371,22 @@ AC_HELP_STRING([--disable-sctp],[Disable SCTP support]),
if test "$sctp" = yes; then if test "$sctp" = yes; then
AC_CHECK_HEADER(netinet/sctp.h, [ AC_CHECK_HEADER(netinet/sctp.h, [
AC_CHECK_LIB(sctp, sctp_bindx, AC_SEARCH_LIBS(sctp_bindx, sctp,
[ [
AC_SUBST(LIBSCTP_LD, -lsctp)
AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.]) AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.])
], sctp=no) ], sctp=no)
], sctp=no) ], sctp=no)
LIBSCTP_LD=$ac_cv_search_sctp_bindx
if test "$LIBSCTP_LD" = "none required"; then
unset LIBSCTP_LD
elif test "$LIBSCTP_LD" = no; then
unset LIBSCTP_LD
fi
AC_SUBST(LIBSCTP_LD)
fi fi

View file

@ -371,14 +371,14 @@ rb_setsockopt_sctp(rb_fde_t *F)
struct sctp_paddrparams paddrparams; struct sctp_paddrparams paddrparams;
struct sctp_assocparams assocparams; struct sctp_assocparams assocparams;
ret = setsockopt(F->fd, SOL_SCTP, SCTP_NODELAY, &opt_one, sizeof(opt_one)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_NODELAY, &opt_one, sizeof(opt_one));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_NODELAY for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_NODELAY for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));
return ret; return ret;
} }
ret = setsockopt(F->fd, SOL_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &opt_mapped, sizeof(opt_mapped)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &opt_mapped, sizeof(opt_mapped));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot unset SCTP_I_WANT_MAPPED_V4_ADDR for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot unset SCTP_I_WANT_MAPPED_V4_ADDR for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));
@ -390,7 +390,7 @@ rb_setsockopt_sctp(rb_fde_t *F)
initmsg.sinit_num_ostreams = 1; initmsg.sinit_num_ostreams = 1;
initmsg.sinit_max_instreams = 1; initmsg.sinit_max_instreams = 1;
ret = setsockopt(F->fd, SOL_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_INITMSG for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_INITMSG for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));
@ -403,7 +403,7 @@ rb_setsockopt_sctp(rb_fde_t *F)
rtoinfo.srto_min = 1000; rtoinfo.srto_min = 1000;
rtoinfo.srto_max = 10000; rtoinfo.srto_max = 10000;
ret = setsockopt(F->fd, SOL_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_RTOINFO for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_RTOINFO for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));
@ -424,7 +424,7 @@ rb_setsockopt_sctp(rb_fde_t *F)
paddrparams.spp_hbinterval = 5000; paddrparams.spp_hbinterval = 5000;
paddrparams.spp_flags |= SPP_HB_ENABLE; paddrparams.spp_flags |= SPP_HB_ENABLE;
ret = setsockopt(F->fd, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(paddrparams)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(paddrparams));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_PEER_ADDR_PARAMS for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_PEER_ADDR_PARAMS for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));
@ -436,7 +436,7 @@ rb_setsockopt_sctp(rb_fde_t *F)
assocparams.sasoc_assoc_id = 0; assocparams.sasoc_assoc_id = 0;
assocparams.sasoc_asocmaxrxt = 50; assocparams.sasoc_asocmaxrxt = 50;
ret = setsockopt(F->fd, SOL_SCTP, SCTP_ASSOCINFO, &assocparams, sizeof(assocparams)); ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_ASSOCINFO, &assocparams, sizeof(assocparams));
if (ret) { if (ret) {
rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_ASSOCINFO for fd %d: %s", rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_ASSOCINFO for fd %d: %s",
F->fd, strerror(rb_get_sockerr(F))); F->fd, strerror(rb_get_sockerr(F)));