uhttpd: restart when interface to listen becomes available
authorDaniel Golle <daniel@makrotopia.org>
Thu, 2 Nov 2023 15:39:49 +0000 (15:39 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Thu, 1 Feb 2024 00:52:54 +0000 (00:52 +0000)
Currently uhttpd won't start with a listening interface configured if
the interface isn't already up at the time uhttpd starts. Make sure we
attempt to start uhttpd when it comes up.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
package/network/services/uhttpd/files/uhttpd.init

index bfde231bf62f700bb87d4b1d4b507a12e3854e66..c4d0025d699e69e40be9a4fccd24c630caed2462 100755 (executable)
@@ -219,10 +219,76 @@ start_instance()
        procd_close_instance
 }
 
+uhttpd_interfaces()
+{
+       local cfg="$1"
+       local http https listen ips
+
+       config_get http "$cfg" listen_http
+       config_get https "$cfg" listen_https
+       for listen in $http $https; do
+               case "$listen" in
+               "" |\
+               "0.0.0.0:"* |\
+               "[::]:"* )
+                       continue
+                       ;;
+               *.*.*.*:*)
+                       ips="$ips ${listen%%:*}
+"
+                       ;;
+               \[*\]:* )
+                       listen="${listen:1}"
+                       ips="$ips ${listen%%]:*}
+"
+                       ;;
+               esac
+       done
+       ips="$( echo "$ips" | sort -u )"
+       echo "$ips"
+}
+
+resolve_iface()
+{
+       local cfg="$1"
+       local ipaddr ipaddrs testip="$2"
+
+       config_get ipaddrs "$cfg" ipaddr
+       for ipaddr in $ipaddrs; do
+               [ "$ipaddr" = "$testip" ] && echo "$cfg"
+       done
+}
+
+get_interface_by_ip()
+{
+       config_load network
+       config_foreach resolve_iface interface "$@"
+}
+
 service_triggers()
 {
+       local iface ifaces all=0
+
        procd_add_reload_trigger "uhttpd"
        procd_add_raw_trigger acme.renew 5000 /etc/init.d/uhttpd reload
+
+       config_load uhttpd
+       ips="$(config_foreach uhttpd_interfaces uhttpd)"
+       [ -z "$ips" ] && return 0
+
+       for ip in $ips; do
+               iface="$(get_interface_by_ip $ip)"
+               [ -z "$iface" ] && all=1
+               ifaces="$ifaces $iface"
+       done
+
+       if [ "$all" = "1" ]; then
+               procd_add_raw_trigger "interface.*.up" 1000 /etc/init.d/uhttpd start
+       else
+               for iface in $ifaces; do
+                       procd_add_raw_trigger "interface.$iface.up" 1000 /etc/init.d/uhttpd start
+               done
+       fi
 }
 
 start_service() {