#!/usr/bin/env bash
# VICIfast Research, Report 01: "The Two Bottlenecks Inside a Busy VICIdial Server"
# Check 4: is the kernel dropping voice packets?
#
# READ-ONLY. Reads /proc/net/snmp twice, 10 seconds apart.
# Usage:  sudo bash linux-check-udp.sh
#
# With Linux's default receive buffers a busy dialer overflows in bursts and
# drops RTP. Agents hear it as choppy audio; nothing in Asterisk logs it.
set -u
rcv() { awk '/^Udp:/ { if (!h) { for (i = 1; i <= NF; i++) n[$i] = i; h = 1 } else print $n["RcvbufErrors"] }' /proc/net/snmp; }
echo "== UDP check on $(hostname -s), $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo "-- net.core.rmem_default=$(sysctl -n net.core.rmem_default)  net.core.rmem_max=$(sysctl -n net.core.rmem_max)"
up=$(awk '{ print int($1) }' /proc/uptime)
a=$(rcv); sleep 10; b=$(rcv)
echo "-- receive-buffer drops since boot: ${b} ($(( b * 3600 / (up > 0 ? up : 1) )) an hour on average)"
echo "-- in the last 10 seconds: $(( b - a ))"
echo
echo "-- Verdict"
if [ $(( b - a )) -gt 0 ]; then
  echo "   Dropping packets now. Raise the buffers (section 8 of the report):"
  echo "     printf 'net.core.rmem_default=4194304\\nnet.core.rmem_max=16777216\\n' > /etc/sysctl.d/99-udp-rmem.conf"
  echo "     sysctl --system      # new sockets pick it up; no restart needed"
elif [ "$(sysctl -n net.core.rmem_default)" -lt 1048576 ] && [ "$b" -gt 0 ]; then
  echo "   No drops in this window, but ${b} since boot on default-sized buffers: check at your busiest hour."
else
  echo "   No drops."
fi
