diff --git a/net/ddns-scripts/CHANGELOG b/net/ddns-scripts/CHANGELOG index 43f3bf8e7..4268c4b4a 100644 --- a/net/ddns-scripts/CHANGELOG +++ b/net/ddns-scripts/CHANGELOG @@ -1,20 +1,39 @@ +Version 2.1.0-3 +Date 2014-12-07 + +- removed special handling for dynamic_dns_helper.sh and url_escape.sed in Makefile/postinst +- minor fixes in logging +- allow retry_count of "0" to run infinite retrys on error + -- https://dev.openwrt.org/ticket/18382 +- changed naming of .dat and .err file to have one per section, not one per process +- defer hotplug helper from 25-ddns to 95-ddns (according initscript START=95) + -- https://github.com/openwrt/packages/issues/568 (#568) +- fix commandline for busybox wget + -- https://dev.openwrt.org/ticket/18411 + -- https://dev.openwrt.org/ticket/18437 + -- https://github.com/openwrt/packages/issues/605 (#605) +- remove checking answer from ddns provider because there are to many different. +Many providers did not follow API from dyndns.com + +-------------------------------------------------------------------------------- Version 2.1.0-2 Date 2014-11-15 - moved /usr/lib/ddns/dynamic_dns_lucihelper.sh from luci-app-ddns into this package - (Github openwrt/luci issue 251) - (OpenWrt Trac tickets 18326 18347) + -- https://github.com/openwrt/luci/issue/251 + -- https://dev.openwrt.org/ticket/18326 + -- https://dev.openwrt.org/ticket/18347 - fix: dynamic_dns_update.sh did not loop - (OpenWrt Trac ticket 18336) + -- https://dev.openwrt.org/ticket/18336 - add provider cloudflare.com IPv4 and IPv6 (Thanks to Paul for support and testing) - (OpenWrt Trac ticket 12500) + -- https://dev.openwrt.org/ticket/12500 - modified detection, if dynamic_dns_fuctions are used by dynamic_dns_lucihelper.sh - redirect stdout of wget,curl,host,nslookup,nc etc to /tmp/ddns_$$.dat and *.err instead of variables - extended error detection in get_local_ip function - modified verify of option ip_script to allow parameters, when calling - add provider selfhost.de IPv4 - add provider no-ip.pl (nothing to do with no-ip.com) - (Github openwrt/packages issue #542) + -- https://github.com/openwrt/packages/issues/542 (#542) IPv4 (tested) and also added for IPv6 (NOT tested) because client IP is autodetected be provider - add getlocalip_sample.sh as sample script for usage of diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile index a64b683f7..29d513c1e 100644 --- a/net/ddns-scripts/Makefile +++ b/net/ddns-scripts/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-scripts PKG_VERSION:=2.1.0 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_LICENSE:=GPL-2.0 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) @@ -19,8 +19,7 @@ define Package/ddns-scripts endef define Package/ddns-scripts/description - A highly configurable set of scripts for doing dynamic dns updates. - NEW in this version: +A highly configurable set of scripts for doing dynamic dns updates. - IPv6 support - force communication to IPv4 or IPv6 only - DNS server support @@ -29,6 +28,7 @@ define Package/ddns-scripts/description - Proxy server support - log file support - support to run once +Version: $(PKG_VERSION)-$(PKG_RELEASE) endef define Build/Prepare @@ -64,14 +64,6 @@ define Package/ddns-scripts/postinst # if run within buildroot exit [ -n "$${IPKG_INSTROOT}" ] && exit 0 - # remove old sed script file - [ -f /usr/lib/ddns/url_escape.sed ] && rm -f /usr/lib/ddns/url_escape.sed - - # luci updates are not in sync with ddns-script updates !!! - # if old luci-app-ddns then errors during install because exist from differnt package - # copy dynamic_dns_helper.tmp.sh -> dynamic_dns_helper.sh - cp -f /usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh /usr/lib/ddns/dynamic_dns_lucihelper.sh - # add new section "ddns" "global" if not exists uci -q get ddns.global > /dev/null || uci -q set ddns.global='ddns' uci -q get ddns.global.date_format > /dev/null || uci -q set ddns.global.date_format='%F %R' diff --git a/net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns b/net/ddns-scripts/files/etc/hotplug.d/iface/95-ddns similarity index 100% rename from net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns rename to net/ddns-scripts/files/etc/hotplug.d/iface/95-ddns 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 old mode 100644 new mode 100755 index 8c0c5c12a..8b3d1ae8a --- a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh @@ -34,13 +34,15 @@ VERBOSE_MODE=1 # default mode is log to console, but easily changed with parame # directory to store run information to. RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns" +[ -d $RUNDIR ] || mkdir -p -m755 $RUNDIR # NEW # directory to store log files LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns" +[ -d $LOGDIR ] || mkdir -p -m755 $LOGDIR LOGFILE="" # NEW # logfile can be enabled as new option PIDFILE="" # pid file UPDFILE="" # store UPTIME of last update -DATFILE="/tmp/ddns_$$.dat" # save stdout data of WGet and other extern programs called -ERRFILE="/tmp/ddns_$$.err" # save stderr output of WGet and other extern programs called +DATFILE="" # save stdout data of WGet and other extern programs called +ERRFILE="" # save stderr output of WGet and other extern programs called # number of lines to before rotate logfile LOGLINES=$(uci -q get ddns.global.log_lines) || LOGLINES=250 @@ -224,7 +226,6 @@ write_log() { [ $VERBOSE_MODE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG" # write to logfile if [ ${use_logfile:-1} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then - [ -d $LOGDIR ] || mkdir -p -m 755 $LOGDIR echo -e "$__MSG" >> $LOGFILE # VERBOSE_MODE > 1 then NO loop so NO truncate log to $LOGLINES lines [ $VERBOSE_MODE -gt 1 ] || sed -i -e :a -e '$q;N;'$LOGLINES',$D;ba' $LOGFILE @@ -302,8 +303,7 @@ get_service_data() { awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\"" }; { print $0 }') IFS=$__NEWLINE_IFS - for __LINE in $__SERVICES - do + for __LINE in $__SERVICES; do #grep out proper parts of data and use echo to remove quotes __NAME=$(echo $__LINE | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo) __DATA=$(echo $__LINE | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo) @@ -459,7 +459,7 @@ verify_host_port() { # command error [ $__ERR -gt 0 ] && { write_log 3 "DNS Resolver Error - BusyBox nslookup Error '$__ERR'" - write_log 7 "Error:\n$(cat $ERRFILE)" + write_log 7 "$(cat $ERRFILE)" return 2 } # extract IP address @@ -499,7 +499,7 @@ verify_host_port() { __ERR=$? [ $__ERR -eq 0 ] && return 0 write_log 3 "Connect error - BusyBox nc (netcat) Error '$__ERR'" - write_log 7 "Error:\n$(cat $ERRFILE)" + write_log 7 "$(cat $ERRFILE)" return 3 else # nc compiled without extensions (no timeout support) __RUNPROG="timeout 2 -- /usr/bin/nc $__IP $__PORT $DATFILE 2>$ERRFILE" @@ -533,7 +533,7 @@ verify_dns() { elif [ $__ERR -ne 0 ]; then __CNT=$(( $__CNT + 1 )) # increment error counter # if error count > retry_count leave here - [ $__CNT -gt $retry_count ] && \ + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ write_log 14 "Verify DNS server '$1' failed after $retry_count retries" write_log 4 "Verify DNS server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" @@ -593,7 +593,7 @@ verify_proxy() { elif [ $__ERR -gt 0 ]; then __CNT=$(( $__CNT + 1 )) # increment error counter # if error count > retry_count leave here - [ $__CNT -gt $retry_count ] && \ + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ write_log 14 "Verify Proxy server '$1' failed after $retry_count retries" write_log 4 "Verify Proxy server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" @@ -637,7 +637,7 @@ do_transfer() { # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set) [ -z "$proxy" ] && __PROG="$__PROG --no-proxy" - __RUNPROG="$__PROG $__URL" # build final command + __RUNPROG="$__PROG '$__URL'" # build final command __PROG="GNU Wget" # reuse for error logging # 2nd choice is cURL IPv4/IPv6/HTTPS @@ -671,7 +671,7 @@ do_transfer() { write_log 13 "cURL: libcurl compiled without Proxy support" fi - __RUNPROG="$__PROG $__URL" # build final command + __RUNPROG="$__PROG '$__URL'" # build final command __PROG="cURL" # reuse for error logging # busybox Wget (did not support neither IPv6 nor HTTPS) @@ -686,8 +686,8 @@ do_transfer() { # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set) [ -z "$proxy" ] && __PROG="$__PROG -Y off" - __RUNPROG="$__PROG $__URL 2>$ERRFILE" # build final command - __PROG="Busybox Wget" # reuse for error logging + __RUNPROG="$__PROG '$__URL' 2>$ERRFILE" # build final command + __PROG="Busybox Wget" # reuse for error logging else write_log 13 "Neither 'Wget' nor 'cURL' installed or executable" @@ -695,7 +695,7 @@ do_transfer() { while : ; do write_log 7 "#> $__RUNPROG" - $__RUNPROG # DO transfer + eval $__RUNPROG # DO transfer __ERR=$? # save error code [ $__ERR -eq 0 ] && return 0 # no error leave [ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script @@ -711,7 +711,7 @@ do_transfer() { __CNT=$(( $__CNT + 1 )) # increment error counter # if error count > retry_count leave here - [ $__CNT -gt $retry_count ] && \ + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ write_log 14 "Transfer failed after $retry_count retries" write_log 4 "Transfer failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" @@ -750,11 +750,11 @@ send_update() { write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)" - # analyse provider answers - # "good [IP_ADR]" = successful - # "nochg [IP_ADR]" = no change but OK - grep -E "good|nochg" $DATFILE >/dev/null 2>&1 - return $? # "0" if "good" or "nochg" found + return 0 + # TODO analyse providers answer + # "good" or "nochg" = dyndns.com compatible API + # grep -i -E "good|nochg" $DATFILE >/dev/null 2>&1 + # return $? # "0" if found fi } @@ -846,6 +846,9 @@ get_local_ip () { } [ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script + + write_log 7 "Data detected:\n$(cat $DATFILE)" + [ $VERBOSE_MODE -gt 1 ] && { # VERBOSE_MODE > 1 then NO retry write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error" @@ -854,9 +857,8 @@ get_local_ip () { __CNT=$(( $__CNT + 1 )) # increment error counter # if error count > retry_count leave here - [ $__CNT -gt $retry_count ] && \ + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ write_log 14 "Get local IP via '$ip_source' failed after $retry_count retries" - write_log 4 "Get local IP via '$ip_source' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" sleep $RETRY_SECONDS & PID_SLEEP=$! @@ -908,7 +910,7 @@ get_registered_ip() { __ERR=$? if [ $__ERR -ne 0 ]; then write_log 3 "$__PROG error: '$__ERR'" - write_log 7 "Error:\n$(cat $ERRFILE)" + write_log 7 "$(cat $ERRFILE)" else if [ "$__PROG" = "BIND host" ]; then __DATA=$(cat $DATFILE | awk -F "address " '/has/ {print $2; exit}' ) @@ -934,7 +936,7 @@ get_registered_ip() { __CNT=$(( $__CNT + 1 )) # increment error counter # if error count > retry_count leave here - [ $__CNT -gt $retry_count ] && \ + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ write_log 14 "Get registered/public IP for '$domain' failed after $retry_count retries" write_log 4 "Get registered/public IP for '$domain' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" @@ -966,18 +968,19 @@ trap_handler() { [ $PID_SLEEP -ne 0 ] && kill -$1 $PID_SLEEP 2>/dev/null # kill pending sleep if exist case $1 in - 0) if [ $__ERR -eq 0 ]; then + 0) if [ $__ERR -eq 0 ]; then write_log 5 "PID '$$' exit normal at $(eval $DATE_PROG)\n" else write_log 4 "PID '$$' exit WITH ERROR '$__ERR' at $(eval $DATE_PROG)\n" fi ;; - 1) write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)" - eval "$0 $SECTION_ID $VERBOSE_MODE &" # reload config via restarting script - exit 0 ;; - 2) write_log 5 "PID '$$' terminated by 'SIGINT' at $(eval $DATE_PROG)\n";; - 3) write_log 5 "PID '$$' terminated by 'SIGQUIT' at $(eval $DATE_PROG)\n";; + 1) write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)" + # reload config via starting the script again + eval "/usr/lib/ddns/dynamic_dns_updater.sh $SECTION_ID $VERBOSE_MODE &" + exit 0 ;; # and leave this one + 2) write_log 5 "PID '$$' terminated by 'SIGINT' at $(eval $DATE_PROG)\n";; + 3) write_log 5 "PID '$$' terminated by 'SIGQUIT' at $(eval $DATE_PROG)\n";; 15) write_log 5 "PID '$$' terminated by 'SIGTERM' at $(eval $DATE_PROG)\n";; - *) write_log 13 "Unhandled signal '$1' in 'trap_handler()'";; + *) write_log 13 "Unhandled signal '$1' in 'trap_handler()'";; esac __PIDS=$(pgrep -P $$) # get my childs (pgrep prints with "newline") diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh similarity index 93% rename from net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh rename to net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh index 1fb758593..c2abecd9a 100755 --- a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh @@ -22,6 +22,8 @@ # preset some variables, wrong or not set in dynamic_dns_functions.sh SECTION_ID="lucihelper" LOGFILE="$LOGDIR/$SECTION_ID.log" +DATFILE="$RUNDIR/$SECTION_ID.dat" # save stdout data of WGet and other extern programs called +ERRFILE="$RUNDIR/$SECTION_ID.err" # save stderr output of WGet and other extern programs called VERBOSE_MODE=0 # no console logging # global variables normally set by reading DDNS UCI configuration use_syslog=0 # no syslog diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh index 349803e40..495c59694 100755 --- a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh @@ -44,6 +44,8 @@ VERBOSE_MODE=${2:-1} # default mode is log to console # set file names PIDFILE="$RUNDIR/$SECTION_ID.pid" # Process ID file UPDFILE="$RUNDIR/$SECTION_ID.update" # last update successful send (system uptime) +DATFILE="$RUNDIR/$SECTION_ID.dat" # save stdout data of WGet and other extern programs called +ERRFILE="$RUNDIR/$SECTION_ID.err" # save stderr output of WGet and other extern programs called LOGFILE="$LOGDIR/$SECTION_ID.log" # log file # VERBOSE_MODE > 1 delete logfile if exist to create an empty one @@ -98,14 +100,14 @@ trap "trap_handler 15" 15 # SIGTERM Termination # # retry_interval if error was detected retry in # retry_unit 'days' 'hours' 'minutes' 'seconds' -# retry_count #NEW# number of retries before scripts stops +# retry_count number of retries before scripts stops # -# use_ipv6 #NEW# detecting/sending IPv6 address -# force_ipversion #NEW# force usage of IPv4 or IPv6 for the whole detection and update communication -# dns_server #NEW# using a non default dns server to get Registered IP from Internet -# force_dnstcp #NEW# force communication with DNS server via TCP instead of default UDP -# proxy #NEW# using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!! -# use_logfile #NEW# self-explanatory "/var/log/ddns/$SECTION_ID.log" +# use_ipv6 detecting/sending IPv6 address +# force_ipversion force usage of IPv4 or IPv6 for the whole detection and update communication +# dns_server using a non default dns server to get Registered IP from Internet +# force_dnstcp force communication with DNS server via TCP instead of default UDP +# proxy using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!! +# use_logfile self-explanatory "/var/log/ddns/$SECTION_ID.log" # # some functionality needs # - GNU Wget or cURL installed for sending updates to DDNS service @@ -138,12 +140,12 @@ esac # set defaults if not defined [ -z "$enabled" ] && enabled=0 [ -z "$retry_count" ] && retry_count=5 -[ -z "$use_syslog" ] && use_syslog=0 # not use syslog +[ -z "$use_syslog" ] && use_syslog=2 # syslog "Notice" [ -z "$use_https" ] && use_https=0 # not use https -[ -z "$use_logfile" ] && use_logfile=1 # NEW - use logfile by default -[ -z "$use_ipv6" ] && use_ipv6=0 # NEW - use IPv4 by default -[ -z "$force_ipversion" ] && force_ipversion=0 # NEW - default let system decide -[ -z "$force_dnstcp" ] && force_dnstcp=0 # NEW - default UDP +[ -z "$use_logfile" ] && use_logfile=1 # use logfile by default +[ -z "$use_ipv6" ] && use_ipv6=0 # use IPv4 by default +[ -z "$force_ipversion" ] && force_ipversion=0 # default let system decide +[ -z "$force_dnstcp" ] && force_dnstcp=0 # default UDP [ -z "$ip_source" ] && ip_source="network" [ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 0 ] && ip_network="wan" # IPv4: default wan [ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 1 ] && ip_network="wan6" # IPv6: default wan6 @@ -185,15 +187,8 @@ write_log 7 "retry counter : $retry_count times" [ -n "$update_script" -a ! -f "$update_script" ] && write_log 14 "Custom update_script not found!" #kill old process if it exists & set new pid file -if [ -d $RUNDIR ]; then - #if process for section is already running, stop it - stop_section_processes "$SECTION_ID" - [ $? -gt 0 ] && write_log 7 "Send 'SIGTERM' to old process" || write_log 7 "No old process" -else - #make dir since it doesn't exist - mkdir -p $RUNDIR - write_log 7 "No old process" -fi +stop_section_processes "$SECTION_ID" +[ $? -gt 0 ] && write_log 7 "Send 'SIGTERM' to old process" || write_log 7 "No old process" echo $$ > $PIDFILE # determine when the last update was @@ -307,7 +302,8 @@ while : ; do if [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then if [ $VERBOSE_MODE -le 1 ]; then # VERBOSE_MODE <=1 then retry ERR_UPDATE=$(( $ERR_UPDATE + 1 )) - [ $ERR_UPDATE -gt $retry_count ] && write_log 14 "Updating IP at DDNS provider failed after $retry_count retries" + [ $retry_count -gt 0 -a $ERR_UPDATE -gt $retry_count ] && \ + write_log 14 "Updating IP at DDNS provider failed after $retry_count retries" write_log 4 "Updating IP at DDNS provider failed - starting retry $ERR_UPDATE/$retry_count" continue # loop to beginning else diff --git a/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh b/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh index ac5dc8e6b..9561f3305 100755 --- a/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh @@ -10,6 +10,11 @@ # # the script is executed (not parsed) inside get_local_ip() function # of /usr/lib/ddns/dynamic_dns_functions.sh +# +# useful when this box is the only DDNS client in the network +# IP adresses of "internal" boxes could be detected with this script +# so no need to install ddns client on every "internal" box +# On IPv6 every internal box normally has it's own external IP # # This script should # - return the IP address via stdout echo -n "...." !!! without line feed