From: Jiang Tengfei Date: Fri, 26 Jun 2026 14:33:11 +0000 (+0800) Subject: ddns-scripts: add curl source IP bind fallback X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=9a5e6063f17bd9f643631ed2fff3ec5236e221dd;p=openwrt-packages.git ddns-scripts: add curl source IP bind fallback 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 --- diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh index 72c5bb052..0f4c5d671 100644 --- a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh @@ -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'" diff --git a/net/ddns-scripts/samples/ddns.config_sample b/net/ddns-scripts/samples/ddns.config_sample index 517a8e652..f30b5ed07 100644 --- a/net/ddns-scripts/samples/ddns.config_sample +++ b/net/ddns-scripts/samples/ddns.config_sample @@ -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"