]> git.99rst.org Git - openwrt-packages.git/commitdiff
ddns-scripts: add curl source IP bind fallback
authorJiang Tengfei <redacted>
Fri, 26 Jun 2026 14:33:11 +0000 (22:33 +0800)
committerFlorian Eckert <redacted>
Tue, 7 Jul 2026 06:02:21 +0000 (08:02 +0200)
Keep the existing cURL bind_network behavior of binding to the
logical device first. This preserves the behavior introduced for
PPPoE and multi-WAN setups where the selected network must also be
used for the DDNS update request.

Some setups can still fail when libcurl binds directly to the logical
PPP device. In that case the transfer may time out even though binding
to the source address of the same network succeeds. This can make DDNS
updates fail repeatedly on affected systems.

Retry cURL transfers once with the network source IP when the
device-bound transfer fails. This leaves the normal path unchanged,
keeps the update request on the same network, and matches the existing
GNU Wget behavior which already binds to the network IP address.

Also document the implicit bind_network default and the cURL fallback
in the sample configuration.

Signed-off-by: Jiang Tengfei <redacted>
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh
net/ddns-scripts/samples/ddns.config_sample

index 72c5bb05233f79c817526035c5175ffe40f98a31..0f4c5d67160d35761f9ca4c607cebf6ed73614f0 100644 (file)
@@ -617,6 +617,7 @@ do_transfer() {
        local __ERR=0
        local __CNT=0   # error counter
        local __PROG  __RUNPROG
+       local __FALLBACK_RUNPROG __FALLBACK_DESC
 
        [ $# -ne 1 ] && write_log 12 "Error in 'do_transfer()' - wrong number of parameters"
 
@@ -674,11 +675,17 @@ do_transfer() {
                        write_log 13 "cURL: libcurl compiled without https support"
                # force network/interface-device to use for communication
                if [ -n "$bind_network" ]; then
-                       local __DEVICE
+                       local __DEVICE __BINDIP __BIND_OPT __FALLBACK_BIND_OPT
                        network_get_device __DEVICE $bind_network || \
                                write_log 13 "Can not detect local device using 'network_get_device $bind_network' - Error: '$?'"
+                       # set correct program to detect IP
+                       [ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" || __RUNPROG="network_get_ipaddr6"
+                       eval "$__RUNPROG __BINDIP $bind_network" || \
+                               write_log 13 "Can not detect current IP using '$__RUNPROG $bind_network' - Error: '$?'"
                        write_log 7 "Force communication via device '$__DEVICE'"
-                       __PROG="$__PROG --interface $__DEVICE"
+                       __BIND_OPT=" --interface $__DEVICE"
+                       __FALLBACK_BIND_OPT=" --interface $__BINDIP"
+                       __FALLBACK_DESC="IP '$__BINDIP'"
                fi
                # force ip version to use
                if [ $force_ipversion -eq 1 ]; then
@@ -705,7 +712,9 @@ do_transfer() {
                        write_log 13 "cURL: libcurl compiled without Proxy support"
                fi
 
-               __RUNPROG="$__PROG '$__URL'"    # build final command
+               __RUNPROG="$__PROG$__BIND_OPT '$__URL'" # build final command
+               [ -n "$__FALLBACK_BIND_OPT" ] && \
+                       __FALLBACK_RUNPROG="$__PROG$__FALLBACK_BIND_OPT '$__URL'"
                __PROG="cURL"                   # reuse for error logging
 
        # uclient-fetch possibly with ssl support if /lib/libustream-ssl.so installed
@@ -765,6 +774,14 @@ do_transfer() {
                eval $__RUNPROG                 # DO transfer
                __ERR=$?                        # save error code
                [ $__ERR -eq 0 ] && return 0    # no error leave
+               if [ -n "$__FALLBACK_RUNPROG" ]; then
+                       write_log 3 "$__PROG Error: '$__ERR'"
+                       write_log 7 "$(cat $ERRFILE)"           # report error
+                       write_log 4 "Transfer failed - retry using $__FALLBACK_DESC"
+                       __RUNPROG="$__FALLBACK_RUNPROG"
+                       __FALLBACK_RUNPROG=""
+                       continue
+               fi
                [ -n "$LUCI_HELPER" ] && return 1       # no retry if called by LuCI helper script
 
                write_log 3 "$__PROG Error: '$__ERR'"
index 517a8e652b1876aafd9033d1d1c390c783696d07..f30b5ed071a5dcaec4a331258b93e5b58f9ab1c0 100644 (file)
@@ -269,10 +269,13 @@ config service "myddns"
        # In some very special configurations i.e. Multi WAN environment
        # in a NAT cascade it might be necessary to define
        # a network to use for communication.
+       # If bind_network is not set and ip_source is "network",
+       # ip_network is used as the default bind network.
        # should use option ip_source "web" (see above)
        # Needs GNU Wget (with SSL support) or cURL to be installed.
-       # GNU Wget will use IP address and cURL the physical device
-       # of the given network
+       # GNU Wget will use IP address and cURL the logical device
+       # of the given network. cURL retries once with the IP address
+       # when the device-bound transfer fails.
        # default: none
 #      option bind_network "wan7"
 
git clone https://git.99rst.org/PROJECT