kamailio-5.x: add ip translation to init
authorSebastian Kemper <[email protected]>
Mon, 5 Nov 2018 21:16:25 +0000 (22:16 +0100)
committerSebastian Kemper <[email protected]>
Mon, 5 Nov 2018 21:17:39 +0000 (22:17 +0100)
kamailio can be started with multiple "-l" ("listen") parameters to tell
it which IPs to listen on. This can also be configured in kamailio.cfg,
of course.

This commit adds the ability to the init script to translate iface names
like "wan" into IP addresses and hand them over to kamailio as command
line arguments. This is useful when using a network connection where IPs
are dynamically assigned.

kamailio can also work with interface names, e.g. "eth0". But it may
listen to all IPs configured on the interface. To avoid this the commit
differentiates beteen IPv4 ("listen") and IPv6 ("listen6"). So if the
user wants kamailio to only listen on an IPv4 address configured on a
certain iface ("wan" for instance), he/she can just specify a list entry
"listen" with that iface.

An explanation is also added to the uci configuration file.

Signed-off-by: Sebastian Kemper <[email protected]>
net/kamailio-5.x/files/kamailio.config
net/kamailio-5.x/files/kamailio.init

index 1f91f85ffef602934e49644d47a8d1e91f2c0b77..aaa9af86daa539538b5c1216e54e5b21a6b8a9d6 100644 (file)
@@ -7,6 +7,15 @@ config kamailio 'general'
        option shm_memory 8
        option pkg_memory 2
        option cfg_file /etc/kamailio/kamailio.cfg
+       # The lists "listen" and "listen6" basically have the same
+       # effect - each list entry will be added to the Kamailio command
+       # line ("-l address"). However, the init script will try to
+       # resolve any interface specifier into an IPv4 ("listen") or
+       # IPv6 ("listen6") address before starting Kamailio. These lists
+       # may be helpful when using dynamic IPs.
+       #list listen udp:wan:5060
+       #list listen udp:192.168.1.1:5060
+       #list listen6 udp:wan:5060
        # Any other option can be put between the quotes below:
        #option options ""
 
index 75a8302b8e89621ef9195960b32a6773a9bc3d64..a7964070d9349a6762128699d366007ac7c4d604 100644 (file)
@@ -15,6 +15,69 @@ USE_PROCD=1
 
 #PROCD_DEBUG=1
 
+check_listen() {
+  local value="$1"
+  local type="$2"
+
+  local address
+  local has_proto=0
+  local one two three
+  local tmp
+
+  [ -z "$value" ] && {
+    $LOG_ERR empty $type entry
+    exit 1
+  }
+
+  # IPv6 addresses need to be enclosed in square brackets. If there are
+  # square brackets in the listen entry, just copy it.
+  echo "$value" | grep "\[[0-9:A-Fa-f]*\]" &> /dev/null && {
+    options=$options" -l $value"
+    return
+  }
+
+  # Bail if more than 2 colons.
+  [ $(echo "$value" | awk -F ":" '{print NF-1}') -gt 2 ] && {
+    $LOG_ERR init script does not understand $type entry \""$value"\"
+    exit 1
+  }
+
+  IFS=":" read one two three << EOF
+$value
+EOF
+
+  case "$one" in
+    udp|tcp|tls|sctp)
+      tmp="$two"
+      has_proto=1
+      ;;
+    *)
+      tmp="$one"
+      ;;
+  esac
+
+  if [ "$type" = "listen" ]; then
+    network_get_ipaddr address "$tmp" || address="$tmp"
+  else
+    network_get_ipaddr6 address "$tmp" && address="[$address]" || \
+                                                     address="$tmp"
+  fi
+
+  if [ -n "$three" ]; then
+    tmp="$one:$address:$three"
+  elif [ -n "$two" ]; then
+    if [ $has_proto = 1 ]; then
+      tmp="$one:$address"
+    else
+      tmp="$address:$two"
+    fi
+  else
+    tmp="$address"
+  fi
+
+  options=$options" -l $tmp"
+}
+
 start_service() {
   local enabled
   local user
@@ -40,6 +103,11 @@ start_service() {
   config_get cfg_file   general cfg_file   /etc/$NAME/$NAME.cfg
   config_get options    general options
 
+  . /lib/functions/network.sh
+
+  config_list_foreach general listen  check_listen listen
+  config_list_foreach general listen6 check_listen listen6
+
   if [ ! -d $RUNDIR ]; then
     mkdir -p $RUNDIR
     chown "$user":"$group" $RUNDIR