#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
MODNAME=xt_RTPENGINE
MANAGE_IPTABLES=yes

DEFAULTS=/etc/default/ngcp-rtpengine-daemon

# Load startup options if available
if [ -f "$DEFAULTS" ]; then
  . "$DEFAULTS" || true
fi

MODPROBE_OPTIONS=""
TABLE=$(/usr/libexec/rtpengine/rtpengine-get-table --config-file="${CONFIG_FILE-/etc/rtpengine/rtpengine.conf}")

# Handle requested setuid/setgid.
if ! test -z "$SET_USER"; then
  PUID=$(id -u "$SET_USER" 2> /dev/null)
  test -z "$PUID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$PUID"
  if test -z "$SET_GROUP"; then
    PGID=$(id -g "$SET_USER" 2> /dev/null)
    test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID"
  fi
fi

if ! test -z "$SET_GROUP"; then
  PGID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null)
  test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID"
fi

if ! test -z "$SET_MASK"; then
  MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_mask=$SET_MASK"
fi

###

if [ -x "$(which ngcp-virt-identify 2>/dev/null)" ]; then
  if ngcp-virt-identify --type container; then
    VIRT="yes"
  fi
fi

firewall_setup()
{
  if [ -z "$TABLE" ] || [ "$TABLE" -lt 0 ] || [ "$VIRT" = "yes" ]; then
    return
  fi

  if [ "$MANAGE_IPTABLES" != "yes" ]; then
    return
  fi

  # shellcheck disable=SC2086
  modprobe $MODNAME $MODPROBE_OPTIONS

  iptables -N rtpengine 2>/dev/null
  iptables -D INPUT -j rtpengine 2>/dev/null
  iptables -D INPUT -p udp -j rtpengine 2>/dev/null
  iptables -I INPUT -p udp -j rtpengine
  iptables -D rtpengine -p udp -j RTPENGINE --id "$TABLE" 2>/dev/null
  iptables -I rtpengine -p udp -j RTPENGINE --id "$TABLE"
  ip6tables -N rtpengine 2>/dev/null
  ip6tables -D INPUT -j rtpengine 2>/dev/null
  ip6tables -D INPUT -p udp -j rtpengine 2>/dev/null
  ip6tables -I INPUT -p udp -j rtpengine
  ip6tables -D rtpengine -p udp -j RTPENGINE --id "$TABLE" 2>/dev/null
  ip6tables -I rtpengine -p udp -j RTPENGINE --id "$TABLE"
}

firewall_teardown()
{
  if [ -z "$TABLE" ] || [ "$TABLE" -lt 0 ] || [ "$VIRT" = "yes" ]; then
    return
  fi

  # The daemon might take a little while to stop: keep trying to remove the
  # table until we can.
  for _ in $(seq 1 10); do
    TABLE_REMOVE_SUCCESS=true
    if [ ! -e /proc/rtpengine/control ]; then
      break
    fi

    if [ ! -d /proc/rtpengine/"$TABLE" ]; then
      break
    fi

    if echo "del $TABLE" >/proc/rtpengine/control 2>/dev/null; then
      break
    fi

    TABLE_REMOVE_SUCCESS=false
    sleep 0.1
  done

  if ! $TABLE_REMOVE_SUCCESS; then
    echo "Failed to remove the iptables kernel table after shutdown of rtpengine." >&2
    return
  fi

  if [ "$MANAGE_IPTABLES" != "yes" ]; then
    return
  fi

  iptables -D rtpengine -p udp -j RTPENGINE --id "$TABLE" 2>/dev/null
  ip6tables -D rtpengine -p udp -j RTPENGINE --id "$TABLE" 2>/dev/null

  # The module refcount might also be delayed going to zero.
  for _ in $(seq 1 10); do
    MODULE_UNLOAD_SUCCESS=true
    if ! lsmod | grep -q "$MODNAME"; then
      break
    fi

    if rmmod "$MODNAME"; then
      break
    fi

    MODULE_UNLOAD_SUCCESS=false
    sleep 0.1
  done

  if ! $MODULE_UNLOAD_SUCCESS; then
      echo "Failed to unload the kernel module $MODNAME." >&2
  fi
}

case "$1" in
  start)
    firewall_setup
    ;;
  stop)
    firewall_teardown
    ;;
  *)
    echo "Usage: $0 {start|stop}" >&2
    exit 1
    ;;
esac

exit 0
