#!/bin/sh
# ==========================================================================
#         _   _      _   ____            __ __  __      _
#        | \ | | ___| |_|  _ \ ___ _ __ / _|  \/  | ___| |_ ___ _ __
#        |  \| |/ _ \ __| |_) / _ \ '__| |_| |\/| |/ _ \ __/ _ \ '__|
#        | |\  |  __/ |_|  __/  __/ |  |  _| |  | |  __/ ||  __/ |
#        |_| \_|\___|\__|_|   \___|_|  |_| |_|  |_|\___|\__\___|_|
#
#                  NetPerfMeter -- Network Performance Meter
#                 Copyright (C) 2009-2026 by Thomas Dreibholz
# ==========================================================================
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# Contact:  dreibh@simula.no
# Homepage: https://www.nntb.no/~dreibh/netperfmeter/

if [ $# -lt 1 ] ; then
   echo >&2 "Usage: $0 [cmt off|normal|rp] [dac on|off] [nrsack on|off] [bufferSplitting none|senderOnly|reeiverOnly|bothSides] [initialCwnd SIZE_IN_MTU] [cwndMaxBurst on|off"
   exit 1
fi


# ====== Get parameters =====================================================
CMT=0
DAC=0
NRSACK=0
BUFFERSPLITTING=0
INITIAL_CWND=3
CWND_MAXBURST=0

while [ "$1" != "" ] ; do
   if [ "$1" = "cmt" ] ; then
      if [ "$2" = "off" ] ; then
         CMT=0
      elif [ "$2" = "cmt" ] || [ "$2" = "normal" ] ; then
         CMT=1
      elif [ "$2" = "cmtrpv1" ] || [ "$2" = "rp" ] ; then
         CMT=2
      elif [ "$2" = "cmtrpv2" ] ; then
         CMT=3
      elif [ "$2" = "like-mptcp" ] || [ "$2" = "mptcp-like" ] || [ "$2" = "mptcp" ] ; then
         CMT=4
      elif [ "$2" -ge 2 ] || [ "$2" -lt 256 ] ; then
         CMT=$2
      else
         echo >&2 "ERROR: Bad setting for cmt!"
         exit 1
      fi
      shift ; shift

   elif [ "$1" = "dac" ] ; then
      if [ "$2" = "on" ] || [ "$2" = "true" ] ; then
         DAC=1
      elif [ "$2" = "off" ] || [ "$2" = "false" ] ; then
         DAC=0
      else
         echo >&2 "ERROR: Bad setting for dac!"
         exit 1
      fi
      shift ; shift

   elif [ "$1" = "nrsack" ] ; then
      if [ "$2" = "on" ] || [ "$2" = "true" ] ; then
         NRSACK=1
      elif [ "$2" = "off" ] || [ "$2" = "false" ] ; then
         NRSACK=0
      else
         echo >&2 "ERROR: Bad setting for nrsack!"
         exit 1
      fi
      shift ; shift

   elif [ "$1" = "cwndMaxBurst" ] ; then
      if [ "$2" = "on" ] || [ "$2" = "true" ] ; then
         CWND_MAXBURST=1
      elif [ "$2" = "off" ] || [ "$2" = "false" ] ; then
         CWND_MAXBURST=0
      else
         echo >&2 "ERROR: Bad setting for cwndMaxBurst!"
         exit 1
      fi
      shift ; shift

   elif [ "$1" = "bufferSplitting" ] ; then
      if [ "$2" = "none" ] ; then
         BUFFERSPLITTING=0
      elif [ "$2" = "senderOnly" ] ; then
         BUFFERSPLITTING=1
      elif [ "$2" = "receiverOnly" ] ; then
         BUFFERSPLITTING=2
      elif [ "$2" = "bothSides" ] ; then
         BUFFERSPLITTING=3
      else
         echo >&2 "ERROR: Bad setting for bufferSplitting!"
         exit 1
      fi
      shift ; shift

   elif [ "$1" = "initialCwnd" ] ; then
      INITIAL_CWND=$2
      shift ; shift

   else
      echo >&2 "ERROR: Unknown setting $1!"
      exit 1
   fi
done


echo "SCTP Configuration:"
echo " - CMT:             $CMT"
echo " - DAC:             $DAC"
echo " - NRSACK:          $NRSACK"
echo " - BUFFERSPLITTING: $BUFFERSPLITTING"
echo " - CWND_MAXBURST:   $CWND_MAXBURST"


success=1
SYSTEM=$(uname)
# ====== FreeBSD QoS setup ==================================================
if [ "$SYSTEM" = "FreeBSD" ] ; then
   /sbin/sysctl net.inet.sctp.cmt_on_off="$CMT" >/dev/null || success=0
   /sbin/sysctl net.inet.sctp.cmt_use_dac=$DAC >/dev/null || success=0
   /sbin/sysctl net.inet.sctp.nr_sack_on_off=$NRSACK >/dev/null || success=0
   /sbin/sysctl net.inet.sctp.buffer_splitting=$BUFFERSPLITTING >/dev/null || success=0
   /sbin/sysctl net.inet.sctp.initial_cwnd="$INITIAL_CWND" >/dev/null || success=0
   /sbin/sysctl net.inet.sctp.cwnd_maxburst=$CWND_MAXBURST >/dev/null || success=0
   /sbin/sysctl kern.ipc.maxsockbuf=1000050000 >/dev/null || success=0      # This is the absolute socket buffer limit!
#   /sbin/sysctl net.inet.sctp.sendspace=10000000 >/dev/null || success=0   # SCTP limit, seems to need full pages!
#   /sbin/sysctl net.inet.sctp.recvspace=10000000 >/dev/null || success=0   # SCTP limit, seems to need full pages!

# ====== Linux ==============================================================
elif [ "$SYSTEM" = "Linux" ] ; then
   # echo >&2 "###### WARNING! setsctp does not usefully support Linux yet ######"

   modprobe sctp

   # /sbin/sysctl net.sctp.auth_enable=1
   # /sbin/sysctl net.sctp.addip_enable=1

# ====== Other systems ======================================================
else
   echo >&2 "ERROR: Unsupported system $SYSTEM!"
   exit 1
fi


# ====== Check whether SCTP configuration has been successful ===============
if [ $success -ne 1 ] ; then
   echo >&2 "ERROR: setsctp has failed to configure sysctl settings!"
   exit 1
fi
