From 0c2d8dbbcb7db9842164799099b41b83467b810e Mon Sep 17 00:00:00 2001 From: Joe Passavanti Date: Mon, 29 Sep 2014 23:15:10 -0700 Subject: [PATCH 01/36] updated to comply with LSBInitScripts see https://wiki.debian.org/LSBInitScripts --- sample-etc_rc.d_init.d_ddclient.ubuntu | 67 ++++++++++++++------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/sample-etc_rc.d_init.d_ddclient.ubuntu b/sample-etc_rc.d_init.d_ddclient.ubuntu index 93b0ba4..0c50bd3 100755 --- a/sample-etc_rc.d_init.d_ddclient.ubuntu +++ b/sample-etc_rc.d_init.d_ddclient.ubuntu @@ -1,8 +1,12 @@ #!/bin/sh -# -# Start ddclient that provides support for updating dynamic DNS services. -# -# Submitted by paolo martinelli +### BEGIN INIT INFO +# Provides: ddclient +# Required-Start: $remote_fs $syslog $network +# Required-Stop: $remote_fs $syslog $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start ddclient daemon at boot time +# Description: Start ddclient that provides support for updating dynamic DNS services. Originally submitted by paolo martinelli, updated by joe passavanti DDCLIENT=/usr/sbin/ddclient CONF=/etc/ddclient/ddclient.conf @@ -14,34 +18,33 @@ test -f $CONF || exit 0 . /lib/lsb/init-functions case "$1" in -start) -log_begin_msg "Starting ddclient..." -DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'` -if [ -z "$DELAY" ] ; then -DELAY="-daemon 300" -else -DELAY='' -fi -start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY -log_end_msg $? -;; -stop) -if [ -f $PIDFILE ] ; then -log_begin_msg "Stopping ddclient..." -start-stop-daemon -K -q -p $PIDFILE -log_end_msg $? -rm -f $PIDFILE -fi -;; -restart|reload|force-reload) -$0 stop -$0 start -;; -*) -log_success_msg "Usage: $0 {start|stop|restart|reload|force-reload}" -exit 1 -;; + start) + log_begin_msg "Starting ddclient..." + DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'` + if [ -z "$DELAY" ] ; then + DELAY="-daemon 300" + else + DELAY='' + fi + start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY + log_end_msg $? + ;; + stop) + if [ -f $PIDFILE ] ; then + log_begin_msg "Stopping ddclient..." + start-stop-daemon -K -q -p $PIDFILE + log_end_msg $? + rm -f $PIDFILE + fi + ;; + restart|reload|force-reload) + $0 stop + $0 start + ;; + *) + log_success_msg "Usage: $0 {start|stop|restart|reload|force-reload}" + exit 1 + ;; esac exit 0 - From 6346cebcc4fdbafd8a23f6127339ac9dc911ce0f Mon Sep 17 00:00:00 2001 From: Joe Passavanti Date: Mon, 29 Sep 2014 23:17:29 -0700 Subject: [PATCH 02/36] added missing end line --- sample-etc_rc.d_init.d_ddclient.ubuntu | 1 + 1 file changed, 1 insertion(+) diff --git a/sample-etc_rc.d_init.d_ddclient.ubuntu b/sample-etc_rc.d_init.d_ddclient.ubuntu index 0c50bd3..348ffd4 100755 --- a/sample-etc_rc.d_init.d_ddclient.ubuntu +++ b/sample-etc_rc.d_init.d_ddclient.ubuntu @@ -7,6 +7,7 @@ # Default-Stop: 0 1 6 # Short-Description: Start ddclient daemon at boot time # Description: Start ddclient that provides support for updating dynamic DNS services. Originally submitted by paolo martinelli, updated by joe passavanti +### END INIT INFO DDCLIENT=/usr/sbin/ddclient CONF=/etc/ddclient/ddclient.conf From 0f7b76630d1c5e065fa94bf47b06a237d84b983d Mon Sep 17 00:00:00 2001 From: George Kranis Date: Sun, 27 Apr 2014 00:44:44 +0300 Subject: [PATCH 03/36] Added Duck DNS --- ddclient | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/ddclient b/ddclient index 8c2d527..a8e8bd4 100755 --- a/ddclient +++ b/ddclient @@ -448,6 +448,10 @@ my %variables = ( 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), }, + 'duckdns-common-defaults' => { + 'server' => setv(T_FQDNP, 1, 0, 1, 'www.duckdns.org', undef), + 'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef), + }, ); my %services = ( 'dyndns1' => { @@ -613,6 +617,15 @@ my %services = ( $variables{'service-common-defaults'}, ), }, + 'duckdns' => { + 'updateable' => undef, + 'update' => \&nic_duckdns_update, + 'examples' => \&nic_duckdns_examples, + 'variables' => merge( + $variables{'duckdns-common-defaults'}, + $variables{'service-common-defaults'}, + ), + }, ); $variables{'merged'} = merge($variables{'global-defaults'}, $variables{'service-common-defaults'}, @@ -4030,6 +4043,83 @@ sub nic_cloudflare_update { } } +###################################################################### +## nic_duckdns_examples +###################################################################### +sub nic_duckdns_examples { + return < Date: Sun, 27 Apr 2014 02:12:44 +0300 Subject: [PATCH 04/36] Duck dns documentation --- ddclient | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ddclient b/ddclient index a8e8bd4..d05cf8d 100755 --- a/ddclient +++ b/ddclient @@ -4050,8 +4050,7 @@ sub nic_duckdns_examples { return < Date: Sun, 2 Nov 2014 05:16:40 +0200 Subject: [PATCH 05/36] Fix false success reporting on failure Add example url --- ddclient | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ddclient b/ddclient index d05cf8d..a6282b9 100755 --- a/ddclient +++ b/ddclient @@ -4071,6 +4071,8 @@ EoEXAMPLE ###################################################################### ## nic_duckdns_update ## by George Kranis (copypasta from nic_dtdns_update) +## http://www.duckdns.org/update?domains=mydomain1,mydomain2&token=xxxx-xxx-xx-x&ip=x.x.x.x +## response contains OK or KO ###################################################################### sub nic_duckdns_update { debug("\nnic_duckdns_update -------------------"); @@ -4103,7 +4105,9 @@ sub nic_duckdns_update { } last if !header_ok($h, $reply); - if ($reply =~ /OK/) + my @reply = split /\n/, $reply; + my $returned = pop(@reply); + if ($returned =~ /OK/) { $config{$h}{'ip'} = $ip; $config{$h}{'mtime'} = $now; @@ -4112,8 +4116,6 @@ sub nic_duckdns_update { } else { - my @reply = split /\n/, $reply; - my $returned = pop(@reply); $config{$h}{'status'} = 'failed'; failed("updating %s: Server said: '$returned'", $h); } From cbe8151a4ed19b0ffc013b18fa6d5cb02792febb Mon Sep 17 00:00:00 2001 From: George Kranis Date: Sun, 2 Nov 2014 05:20:58 +0200 Subject: [PATCH 06/36] Added DuckDNS API url --- ddclient | 1 + 1 file changed, 1 insertion(+) diff --git a/ddclient b/ddclient index a6282b9..978458c 100755 --- a/ddclient +++ b/ddclient @@ -4052,6 +4052,7 @@ o 'duckdns' The 'duckdns' protocol is used by the free dynamic DNS service offered by www.duckdns.org. +Check http://www.duckdns.org/install.jsp?tab=linux-cron for API Configuration variables applicable to the 'duckdns' protocol are: protocol=duckdns ## From 441f58fdb1d95454c1715abfeb4daed23b765d46 Mon Sep 17 00:00:00 2001 From: Tatsuya-Nonogaki Date: Tue, 30 Dec 2014 01:58:57 +0900 Subject: [PATCH 07/36] odd-fw-patch-squashed --- ddclient | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/ddclient b/ddclient index 8c2d527..ce8809a 100755 --- a/ddclient +++ b/ddclient @@ -339,6 +339,7 @@ my %variables = ( 'web-skip' => setv(T_STRING,1, 0, 1, '', undef), 'fw' => setv(T_ANY, 0, 0, 1, '', undef), 'fw-skip' => setv(T_STRING,1, 0, 1, '', undef), + 'fw-banlocal' => setv(T_BOOL, 0, 0, 1, 0, undef), 'fw-login' => setv(T_LOGIN, 1, 0, 1, '', undef), 'fw-password' => setv(T_PASSWD,1, 0, 1, '', undef), 'cmd' => setv(T_PROG, 0, 0, 1, '', undef), @@ -378,6 +379,7 @@ my %variables = ( 'web-skip' => setv(T_STRING,0, 0, 1, '', undef), 'fw' => setv(T_ANY, 0, 0, 1, '', undef), 'fw-skip' => setv(T_STRING,0, 0, 1, '', undef), + 'fw-banlocal' => setv(T_BOOL, 0, 0, 1, 0, undef), 'fw-login' => setv(T_LOGIN, 0, 0, 1, '', undef), 'fw-password' => setv(T_PASSWD,0, 0, 1, '', undef), 'cmd' => setv(T_PROG, 0, 0, 1, '', undef), @@ -645,6 +647,7 @@ my @opt = ( "", [ "fw", "=s", "-fw address|url : obtain IP address from firewall at 'address'" ], [ "fw-skip", "=s", "-fw-skip pattern : skip any IP addresses before 'pattern' on the firewall address|url" ], + [ "fw-banlocal", "!", "-fw-banlocal : ignore local IP addresses on the firewall address|url" ], [ "fw-login", "=s", "-fw-login login : use 'login' when getting IP from fw" ], [ "fw-password", "=s", "-fw-password secret : use password 'secret' when getting IP from fw" ], "", @@ -1984,6 +1987,48 @@ sub geturl { return $reply; } ###################################################################### +## un_zero_pad +###################################################################### +sub un_zero_pad { + my $in_str = shift(@_); + my @out_str = (); + + if ($in_str eq '0.0.0.0') { + return $in_str; + } + + foreach my $block (split /\./, $in_str) { + $block =~ s/^0+//; + if ($block eq '') { + $block = '0'; + } + push @out_str, $block; + } + return join('.', @out_str); +} +###################################################################### +## filter_local +###################################################################### +sub filter_local { + my $in_ip = shift(@_); + + if ($in_ip eq '0.0.0.0') { + return $in_ip; + } + + my @guess_local = ( + '^10\.', + '^172\.(?:1[6-9]|2[0-9]|3[01])\.', + '^192\.168' + ); + foreach my $block (@guess_local) { + if ($in_ip =~ /$block/) { + return '0.0.0.0'; + } + } + return $in_ip; +} +###################################################################### ## get_ip ###################################################################### sub get_ip { @@ -2080,6 +2125,8 @@ sub get_ip { } if ($reply =~ /^.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b.*/is) { $ip = $1; + $ip = un_zero_pad($ip); + $ip = filter_local($ip) if opt('fw-banlocal', $h); } if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) { $ip = undef; From 57e1a444481091988e12df44c3ae918c07926a42 Mon Sep 17 00:00:00 2001 From: Kym Eden Date: Tue, 3 Mar 2015 09:11:06 +0000 Subject: [PATCH 08/36] Add missing config line for CloudFlare --- ddclient | 1 + 1 file changed, 1 insertion(+) diff --git a/ddclient b/ddclient index b0550f6..1395f07 100755 --- a/ddclient +++ b/ddclient @@ -613,6 +613,7 @@ my %services = ( { 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef) }, { 'min-interval' => setv(T_DELAY, 0, 0, 1, interval('5m'), 0),}, $variables{'cloudflare-common-defaults'}, + $variables{'service-common-defaults'}, ), }, 'googledomains' => { From 536f685c05da8e9605e7cc2625673aecd9ce606b Mon Sep 17 00:00:00 2001 From: reddyr Date: Fri, 20 Mar 2015 15:33:59 -0700 Subject: [PATCH 09/36] loopia.se changed the "Current Address:" output string to "Current IP Address:" --- ddclient | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient b/ddclient index b0550f6..1b5e32e 100755 --- a/ddclient +++ b/ddclient @@ -72,7 +72,7 @@ my %builtinweb = ( 'dyndns' => { 'url' => 'http://checkip.dyndns.org/', 'skip' => 'Current IP Address:', }, 'dnspark' => { 'url' => 'http://ipdetect.dnspark.com/', 'skip' => 'Current Address:', }, - 'loopia' => { 'url' => 'http://dns.loopia.se/checkip/checkip.php', 'skip' => 'Current Address:', }, + 'loopia' => { 'url' => 'http://dns.loopia.se/checkip/checkip.php', 'skip' => 'Current IP Address:', }, ); my %builtinfw = ( 'watchguard-soho' => { From f6409c756dc62fac79df20d565c40a899986d9f9 Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Sat, 21 Mar 2015 12:57:37 +0100 Subject: [PATCH 10/36] Added duckDNS to the README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index edd0dc7..a83a1e1 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Dynamic DNS services currently supported include: nsupdate - See nsupdate(1) and ddns-confgen(8) for details CloudFlare - See https://www.cloudflare.com/ for details Google - See http://www.google.com/domains for details + Duckdns - See https://duckdns.org/ for details DDclient now supports many of cable/dsl broadband routers. From 87a0260c8896cba6591f3004050f1101483ec6fb Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Mon, 23 Mar 2015 19:24:01 +0100 Subject: [PATCH 11/36] ddclient: correction after duckdns merge Correcting duckdns configuration after commit 0c9920a1 --- ddclient | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ddclient b/ddclient index 0100b98..e4d75a0 100755 --- a/ddclient +++ b/ddclient @@ -450,10 +450,11 @@ my %variables = ( }, 'googledomains-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 1, 'domains.google.com', undef), - 'duckdns-common-defaults' => { - 'server' => setv(T_FQDNP, 1, 0, 1, 'www.duckdns.org', undef), - 'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef), - }, + }, + 'duckdns-common-defaults' => { + 'server' => setv(T_FQDNP, 1, 0, 1, 'www.duckdns.org', undef), + 'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef), + }, ); my %services = ( 'dyndns1' => { From 119588f40feb8fed281cf37c14004ae676e952de Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Mon, 23 Mar 2015 19:25:58 +0100 Subject: [PATCH 12/36] ddclient: reindenting cloudflare Indenting cloudflare according to the vim tags --- ddclient | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ddclient b/ddclient index e4d75a0..b7b4f9e 100755 --- a/ddclient +++ b/ddclient @@ -440,14 +440,14 @@ my %variables = ( 'ttl' => setv(T_NUMBER, 0, 1, 0, 600, undef), 'zone' => setv(T_STRING, 1, 1, 1, '', undef), }, - 'cloudflare-common-defaults' => { - 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef), - 'zone' => setv(T_FQDN, 1, 0, 1, '', undef), - 'static' => setv(T_BOOL, 0, 1, 1, 0, undef), - 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), - 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), - 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), - }, + 'cloudflare-common-defaults' => { + 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef), + 'zone' => setv(T_FQDN, 1, 0, 1, '', undef), + 'static' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), + 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), + }, 'googledomains-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 1, 'domains.google.com', undef), }, From 98060e2836be520941ae2bd177b9a3ca55d467a5 Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Mon, 23 Mar 2015 19:27:38 +0100 Subject: [PATCH 13/36] ddclient: made json optional As suggested in pull #7 by @abelbeck and @Bugsbane it is better to make the use of JSON related to the use of cloudflare. --- ddclient | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ddclient b/ddclient index b7b4f9e..330557c 100755 --- a/ddclient +++ b/ddclient @@ -25,7 +25,6 @@ use strict; use Getopt::Long; use Sys::Hostname; use IO::Socket; -use JSON::Any; # my ($VERSION) = q$Revision: 161 $ =~ /(\d+)/; @@ -1296,6 +1295,7 @@ sub init_config { $proto = opt('protocol') if !defined($proto); load_sha1_support() if ($proto eq "freedns"); + load_json_support() if ($proto eq "cloudflare"); if (!exists($services{$proto})) { warning("skipping host: %s: unrecognized protocol '%s'", $h, $proto); @@ -1875,6 +1875,18 @@ EOM } } ###################################################################### +## load_json_support +###################################################################### +sub load_json_support { + my $json_loaded = eval {require JSON::Any}; + unless ($json_loaded) { + fatal(<<"EOM"); +Error loading the Perl module JSON::Any needed for cloudflare update. +EOM + } + import JSON::Any; +} +###################################################################### ## geturl ###################################################################### sub geturl { From 7a3d0f99ce6fcb78856e4734e2c7ed2d6f7c668d Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Fri, 8 May 2015 22:04:42 +0200 Subject: [PATCH 14/36] Reverting to the old perl requirements like suggested in #75 The new requirements were added when adding support for cloudflare. By the simple fix suggested by Roy Tam we could revert the requirements which make ddclient back usable on CentOS and RHEL. --- ddclient | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddclient b/ddclient index 330557c..5862d3f 100755 --- a/ddclient +++ b/ddclient @@ -20,7 +20,7 @@ # # ###################################################################### -require 5.014; +require 5.004; use strict; use Getopt::Long; use Sys::Hostname; @@ -4075,7 +4075,7 @@ sub nic_cloudflare_update { # FQDNs for my $domain (@hosts) { - my $hostname = $domain =~ s/\.$config{$key}{zone}$//r; + (my $hostname = $domain) =~ s/\.$config{$key}{zone}$//; delete $config{$domain}{'wantip'}; info("setting IP address to %s for %s", $ip, $domain); From 1d919b15a394b3b40fd1bb24ceb665d89d54b108 Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Thu, 28 May 2015 22:05:05 +0200 Subject: [PATCH 15/36] Preparing for v3.8.3 --- ChangeLog | 147 +++++++++++++++++++++++++++++++++++++++++++++++++--- RELEASENOTE | 17 +++--- ddclient | 6 +-- 3 files changed, 152 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 092c2f1..868a8ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,141 @@ +2015-05-28 wimpunk + + * [r183] ., release: Removing unneeded release directory + +2015-03-23 wimpunk + + * [r182] ddclient: Reverting to the old perl requirements like + suggested in #75 + + The new requirements were added when adding support for cloudflare. By the + simple fix suggested by Roy Tam we could revert the requirements which make + ddclient back usable on CentOS and RHEL. + + * [r181] ddclient: ddclient: made json optional + + As suggested in pull 7 on github by @abelbeck and @Bugsbane it is + better to make the + use of JSON related to the use of cloudflare. + + * [r180] ddclient: ddclient: reindenting cloudflare + + Indenting cloudflare according to the vim tags + + * [r179] ddclient: ddclient: correction after duckdns merge + + Correcting duckdns configuration after commit r178 + + * [r178] ddclient: Added simple support for Duckdns www.duckdns.org + + Patch provided by gkranis on github. + Merge branch 'gkranis' + +2015-03-21 wimpunk + + * [r177] README.md: Added duckDNS to the README.md + * [r176] sample-etc_rc.d_init.d_ddclient.ubuntu: update ubuntu init.d script + + Merge pull request #9 from gottaloveit/master + + * [r175] Changelog, Changelog.old: Renamed Changelog to + Changelog.old + + Avoiding conflicts on case insensitive filesystems + + * [r174] ddclient: Add missing config line for CloudFlare + + Merge pull request #19 from shikasta-net/fixes + + * [r173] ddclient: Merge pull request #22 from reddyr/patch-1 + + loopia.se changed the "Current Address:" output string to "Current IP + Address:" + + * [r172] ddclient: fixed missing ) for cloudflare service hash + + Merge pull request #16 from adepretis/master + +2015-01-20 wimpunk + + * [r171] README.md, ddclient, sample-etc_ddclient.conf: Adding + support for google domain + + Patch gently provided through github on + https://github.com/wimpunk/ddclient/pull/13 + +2014-10-08 wimpunk + + * [r170] README.md, ddclient, sample-etc_ddclient.conf: Added + support for Cloudflare and multi domain support for namecheap + + Pull request #7 from @roberthawdon + See https://github.com/wimpunk/ddclient/pull/7 for more info. + +2014-09-09 wimpunk + + * [r169] ddclient: Bugfix: allowing long username-password + combinations + + Patch provided by @dirdi through github. + +2014-08-20 wimpunk + + * [r166] ddclient: Fixing bug #72: Account info revealed during + noip update + + * [r165] ddclient: Interfaces can be named almost anything on + modern systems. + + Patch provided by Stephen Couchman through github + +2014-06-30 wimpunk + + * [r164] ddclient: Only delete A RR, not any RR for the FQDN + + Make the delete command specific to A RRs. This prevents ddclient + from deleting other RRs unrelated to the dynamic address, but on the + same FQDN. This can be specifically a problem with KEY RRs when using + SIG(0) instead of symmetric keys. + + Reported by: Wellie Chao + Bug report: http://sourceforge.net/p/ddclient/bugs/71/ + + Fixes #71 + +2014-06-02 wimpunk + + * [r163] README.md, ddclient: Adding support for nsupdate. + + Patch provided by Daniel Roethlisberger through + github. + +2014-04-29 wimpunk + + * [r162] README.md, README.ssl, ddclient: Removed revision + information + + Revision information isn't very usable when switching to git. + +2014-03-20 wimpunk + + * [r161] README.md, README.ssl, ddclient, + sample-etc_rc.d_init.d_ddclient.alpine: Added Alpine Linux init + script + + Patch send by Tal on github. + + * [r160] RELEASENOTE: Corrected release note + +2013-12-26 wimpunk + + * [r159] release/readme.txt: Commiting updated release information + * [r158] README.md, RELEASENOTE: Committing release notes and + readme information to trunk + 2013-11-05 wimpunk * [r156] patches: Moving patching to the root of the repository. - + The patches are mostly there for historical reasons. They've been moved away to make cleaning easier. I think the applied patches should even be removed. @@ -9,17 +143,17 @@ 2013-10-28 wimpunk * [r155] ddclient: Fallback to iproute if ifconfig doesn't work. - - This fix applies the patch provided by Maccied Grela in - [bugs:#26] + + This fix applies the patch provided by Maccied Grela in [bugs:#26] + * [r154] ddclient: preventing deep sleep - see [bugs:#46] - + Fixing [bugs:#46] by applying the provided patch. 2013-07-08 wimpunk * [r153] ddclient: Applying patch from [fb1ad014] fixing bug [#14] - + More info can be found on [fb1ad014] and has been discussed in the mailinglist: http://article.gmane.org/gmane.network.dns.ddclient.user/71. The @@ -424,4 +558,3 @@ 2006-05-22 wimpunk * [r2] Reorganise - diff --git a/RELEASENOTE b/RELEASENOTE index 9b1edd4..7e40879 100644 --- a/RELEASENOTE +++ b/RELEASENOTE @@ -1,11 +1,12 @@ -It's been a while and has been announced a while ago but here is new release of -ddclient. There are some important changes and some documentation is modified. +Yet again it's been a while but here is new release of ddclient. As usual, +there are some important changes and some documentation is modified. A detailed overview can be found in ChangeLog but here's a quick overview: - * adding support by ChangeIP - patch send by Michele Giorato - * sha-1 patch send by pirast to allow Digest::SHA - * allow reuse of use - patch send by Rodrigo Araujo - * preventing deep sleep - see [bugs:#46] - * Fallback to iproute if ifconfig doesn't work send by Maccied Grela - + * added Alpine Linux init scritp - patch send by @Tal on github. + * adding support for nsupdate - patch send by @droe on github + * allow log username-password combinations - patch send by @dirdi on github + * adding support for cloudflare - patch send by @roberthawdon on github + * adding support for duckdns - patch send by @gkranis +A very big thank you for everyone who created a pull request on github and +for everyone who helped to fix the little issues caused by the new providers. diff --git a/ddclient b/ddclient index 5862d3f..54a31c0 100755 --- a/ddclient +++ b/ddclient @@ -1,7 +1,7 @@ #!/usr/bin/perl -w #!/usr/local/bin/perl -w ###################################################################### -# $Id: ddclient 161 2014-03-20 20:02:14Z wimpunk $ +# $Id: ddclient 184 2015-05-28 19:59:34Z wimpunk $ # # DDCLIENT - a Perl client for updating DynDNS information # @@ -26,9 +26,9 @@ use Getopt::Long; use Sys::Hostname; use IO::Socket; -# my ($VERSION) = q$Revision: 161 $ =~ /(\d+)/; +# my ($VERSION) = q$Revision: 184 $ =~ /(\d+)/; -my $version = "3.8.2"; +my $version = "3.8.3"; my $programd = $0; $programd =~ s%^.*/%%; my $program = $programd; From c497ed04c746f4e7e9341acd5859ea8a4165f908 Mon Sep 17 00:00:00 2001 From: MedicMomcilo Date: Sun, 31 May 2015 01:55:41 +0200 Subject: [PATCH 16/36] FSF address Address for FSF was wrong, corrected --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index 60549be..4d97367 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. From 4a640ed4c0c9698504662f4a57e7c1702adf034a Mon Sep 17 00:00:00 2001 From: George Kranis Date: Mon, 1 Jun 2015 22:02:37 +0300 Subject: [PATCH 17/36] duckdns example --- sample-etc_ddclient.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sample-etc_ddclient.conf b/sample-etc_ddclient.conf index de8bfbc..d988f86 100644 --- a/sample-etc_ddclient.conf +++ b/sample-etc_ddclient.conf @@ -214,3 +214,11 @@ ssl=yes # use ssl-support. Works with # login=my-auto-generated-username, # password=my-auto-generated-password # my.domain.tld, otherhost.domain.tld + +## +## Duckdns (http://www.duckdns.org/) +## +# +# password=my-auto-generated-password +# protocol=duckdns hostwithoutduckdnsorg + From 331a5491afa757faafaef4ea0d68cd789d37a7c4 Mon Sep 17 00:00:00 2001 From: dancapper Date: Tue, 14 Jul 2015 22:11:41 +1200 Subject: [PATCH 18/36] cloudflare - add ttl to config Configurable ttl for cloudflare instead of hardcoded 1 (auto) --- ddclient | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ddclient b/ddclient index 54a31c0..4f7a7ee 100755 --- a/ddclient +++ b/ddclient @@ -446,6 +446,7 @@ my %variables = ( 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'ttl' => setv(T_NUMBER, 1, 0, 1, 1 undef), }, 'googledomains-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 1, 'domains.google.com', undef), @@ -4110,7 +4111,8 @@ sub nic_cloudflare_update { } # Set domain - $url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A&ttl=1"; + $url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A"; + $url .= "$ttl=".$config{$key}{'ttl'}; $url .= "&name=$hostname"; $url .= "&z=".$config{$key}{'zone'}; $url .= "&id=".$id; From a7fce1a9bd17adbcbb3f9fea1b6ea31d759e10ef Mon Sep 17 00:00:00 2001 From: dancapper Date: Tue, 14 Jul 2015 22:13:22 +1200 Subject: [PATCH 19/36] add ttl for cloudflare --- sample-etc_ddclient.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sample-etc_ddclient.conf b/sample-etc_ddclient.conf index de8bfbc..4f872f2 100644 --- a/sample-etc_ddclient.conf +++ b/sample-etc_ddclient.conf @@ -204,7 +204,8 @@ ssl=yes # use ssl-support. Works with #zone=domain.tld, \ #server=www.cloudflare.com, \ #login=your-login-email, \ -#password=APIKey \ +#password=APIKey, \ +#ttl=1 \ #domain.tld,my.domain.tld ## From 17d31e437306bfa46008cd88d9665854ed654c69 Mon Sep 17 00:00:00 2001 From: dancapper Date: Tue, 14 Jul 2015 22:19:02 +1200 Subject: [PATCH 20/36] typo fix --- ddclient | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddclient b/ddclient index 4f7a7ee..7929d6d 100755 --- a/ddclient +++ b/ddclient @@ -446,7 +446,7 @@ my %variables = ( 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), - 'ttl' => setv(T_NUMBER, 1, 0, 1, 1 undef), + 'ttl' => setv(T_NUMBER, 1, 0, 1, 1, undef), }, 'googledomains-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 1, 'domains.google.com', undef), @@ -4112,7 +4112,7 @@ sub nic_cloudflare_update { # Set domain $url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A"; - $url .= "$ttl=".$config{$key}{'ttl'}; + $url .= "&ttl=".$config{$key}{'ttl'}; $url .= "&name=$hostname"; $url .= "&z=".$config{$key}{'zone'}; $url .= "&id=".$id; From 88c2eb46e67b6080238d885d289d6e0b9ed58dd3 Mon Sep 17 00:00:00 2001 From: wimpunk Date: Mon, 28 Sep 2015 19:13:03 +0000 Subject: [PATCH 21/36] Cleanup: removing Id tags from the files Preparing a complete move to git. The Id tag isn't useful so removing from the files seemed to be the best solotion git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@186 3873ddee-7413-0410-b6c4-c2c57c1ab35a --- Changelog.old | 2 -- README.cisco | 1 - ddclient | 1 - sample-etc_cron.d_ddclient | 1 - sample-etc_ddclient.conf | 2 -- sample-etc_dhclient-exit-hooks | 2 -- sample-etc_dhcpc_dhcpcd-eth0.exe | 2 -- sample-etc_ppp_ip-up.local | 2 -- sample-etc_rc.d_init.d_ddclient.lsb | 2 -- sample-etc_rc.d_init.d_ddclient.redhat | 2 +- 10 files changed, 1 insertion(+), 16 deletions(-) diff --git a/Changelog.old b/Changelog.old index c4e6561..478d84b 100644 --- a/Changelog.old +++ b/Changelog.old @@ -299,6 +299,4 @@ Changelog This feature can be used to reissue updates that may have failed due to network connectivity problems or a DynDNS server outage -------------------------------------------------------------------------------- -$Id: Changelog 96 2008-06-13 20:24:24Z wimpunk $ ------------------------------------------------------------------------ diff --git a/README.cisco b/README.cisco index ab7317a..29cb13d 100644 --- a/README.cisco +++ b/README.cisco @@ -1,4 +1,3 @@ -$Id: README.cisco 96 2008-06-13 20:24:24Z wimpunk $ Method 1 ------------------------------------------------------ The following config will allow the Linux machine (10.1.1.2) to read diff --git a/ddclient b/ddclient index 54a31c0..eaedf9a 100755 --- a/ddclient +++ b/ddclient @@ -1,7 +1,6 @@ #!/usr/bin/perl -w #!/usr/local/bin/perl -w ###################################################################### -# $Id: ddclient 184 2015-05-28 19:59:34Z wimpunk $ # # DDCLIENT - a Perl client for updating DynDNS information # diff --git a/sample-etc_cron.d_ddclient b/sample-etc_cron.d_ddclient index eadec1e..1cdff4f 100644 --- a/sample-etc_cron.d_ddclient +++ b/sample-etc_cron.d_ddclient @@ -1,6 +1,5 @@ ###################################################################### ## ddclient is an IP address updater for www.dyndns.org -## $Id: sample-etc_cron.d_ddclient 96 2008-06-13 20:24:24Z wimpunk $ ###################################################################### ## minute 0-59 ## hour 0-23 diff --git a/sample-etc_ddclient.conf b/sample-etc_ddclient.conf index de8bfbc..21e8957 100644 --- a/sample-etc_ddclient.conf +++ b/sample-etc_ddclient.conf @@ -1,7 +1,5 @@ ###################################################################### ## -## $Id: sample-etc_ddclient.conf 150 2013-04-28 14:55:34Z wimpunk $ -## ## Define default global variables with lines like: ## var=value [, var=value]* ## These values will be used for each following host unless overridden diff --git a/sample-etc_dhclient-exit-hooks b/sample-etc_dhclient-exit-hooks index a38716d..a8c2b42 100644 --- a/sample-etc_dhclient-exit-hooks +++ b/sample-etc_dhclient-exit-hooks @@ -1,7 +1,5 @@ #!/bin/sh ###################################################################### -## $Id: sample-etc_dhclient-exit-hooks 96 2008-06-13 20:24:24Z wimpunk $ -###################################################################### # The /etc/dhclient-enter-hooks script is run by the ISC DHCP client's standard # update script whenever dhclient obtains or renews an address. diff --git a/sample-etc_dhcpc_dhcpcd-eth0.exe b/sample-etc_dhcpc_dhcpcd-eth0.exe index 1d9183b..23141c7 100644 --- a/sample-etc_dhcpc_dhcpcd-eth0.exe +++ b/sample-etc_dhcpc_dhcpcd-eth0.exe @@ -1,7 +1,5 @@ #!/bin/sh ###################################################################### -## $Id: sample-etc_dhcpc_dhcpcd-eth0.exe 96 2008-06-13 20:24:24Z wimpunk $ -###################################################################### PATH=/usr/sbin:${PATH} ## update the DNS server unless the IP address is a private address diff --git a/sample-etc_ppp_ip-up.local b/sample-etc_ppp_ip-up.local index 42abc6d..2d634bc 100644 --- a/sample-etc_ppp_ip-up.local +++ b/sample-etc_ppp_ip-up.local @@ -1,7 +1,5 @@ #!/bin/sh ###################################################################### -## $Id: sample-etc_ppp_ip-up.local 128 2011-07-11 20:24:43Z wimpunk $ -###################################################################### ## ## On my host, pppd invokes this script with args: ## /etc/ppp/ip-up.local ppp0 /dev/pts/1 115200 192.168.2.1 192.168.2.3 diff --git a/sample-etc_rc.d_init.d_ddclient.lsb b/sample-etc_rc.d_init.d_ddclient.lsb index 3243139..7252d3f 100755 --- a/sample-etc_rc.d_init.d_ddclient.lsb +++ b/sample-etc_rc.d_init.d_ddclient.lsb @@ -21,8 +21,6 @@ # can be used on many types of firewalls ### END INIT INFO # -# $Id: sample-etc_rc.d_init.d_ddclient.lsb 96 2008-06-13 20:24:24Z wimpunk $ -# ### [ -f /etc/ddclient/ddclient.conf ] || exit 0 diff --git a/sample-etc_rc.d_init.d_ddclient.redhat b/sample-etc_rc.d_init.d_ddclient.redhat index 3de4287..2e0fd32 100755 --- a/sample-etc_rc.d_init.d_ddclient.redhat +++ b/sample-etc_rc.d_init.d_ddclient.redhat @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: sample-etc_rc.d_init.d_ddclient.redhat 96 2008-06-13 20:24:24Z wimpunk $ +# # ddclient This shell script takes care of starting and stopping # ddclient. # From 6fc2f511b6c6b285a32c8448b9524a39b265a7b7 Mon Sep 17 00:00:00 2001 From: Wim Vinckier Date: Mon, 28 Sep 2015 21:38:28 +0200 Subject: [PATCH 22/36] Cleanup: removing revision info from ddclient Preparing the complete merge with sf. --- ddclient | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient b/ddclient index eaedf9a..9b8113b 100755 --- a/ddclient +++ b/ddclient @@ -25,7 +25,7 @@ use Getopt::Long; use Sys::Hostname; use IO::Socket; -# my ($VERSION) = q$Revision: 184 $ =~ /(\d+)/; +# my ($VERSION) = q$Revision$ =~ /(\d+)/; my $version = "3.8.3"; my $programd = $0; From e7290d827b3c2ca7f1db7bff2a4cff2306ef8074 Mon Sep 17 00:00:00 2001 From: wimpunk Date: Mon, 28 Sep 2015 19:41:09 +0000 Subject: [PATCH 23/36] Cleanup: removing revision info. Removing revision info even when it's just in the comments. git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@190 3873ddee-7413-0410-b6c4-c2c57c1ab35a --- ddclient | 2 -- 1 file changed, 2 deletions(-) diff --git a/ddclient b/ddclient index 9b8113b..f0a11fa 100755 --- a/ddclient +++ b/ddclient @@ -25,8 +25,6 @@ use Getopt::Long; use Sys::Hostname; use IO::Socket; -# my ($VERSION) = q$Revision$ =~ /(\d+)/; - my $version = "3.8.3"; my $programd = $0; $programd =~ s%^.*/%%; From 35e6c1a1638c0508193dfbf6d17ce2a36d567cf9 Mon Sep 17 00:00:00 2001 From: Janne Hannila Date: Wed, 2 Sep 2015 02:28:11 +0300 Subject: [PATCH 24/36] Added support for woima.fi dyndns service --- README.md | 1 + ddclient | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) diff --git a/README.md b/README.md index a83a1e1..8ef25a7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Dynamic DNS services currently supported include: CloudFlare - See https://www.cloudflare.com/ for details Google - See http://www.google.com/domains for details Duckdns - See https://duckdns.org/ for details + woima.fi - See https://woima.fi/ for details DDclient now supports many of cable/dsl broadband routers. diff --git a/ddclient b/ddclient index 54a31c0..0bbbceb 100755 --- a/ddclient +++ b/ddclient @@ -454,6 +454,29 @@ my %variables = ( 'server' => setv(T_FQDNP, 1, 0, 1, 'www.duckdns.org', undef), 'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef), }, + 'woima-common-defaults' => { + 'static' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), + 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'custom' => setv(T_BOOL, 0, 1, 1, 0, undef), + 'script' => setv(T_STRING, 1, 1, 1, '/nic/update', undef), + }, + 'woima-service-common-defaults' => { + 'server' => setv(T_FQDNP, 1, 0, 1, 'dyn.woima.fi', undef), + 'login' => setv(T_LOGIN, 1, 0, 1, '', undef), + 'password' => setv(T_PASSWD, 1, 0, 1, '', undef), + 'ip' => setv(T_IP, 0, 1, 0, undef, undef), + 'wtime' => setv(T_DELAY, 0, 1, 1, 0, interval('30s')), + 'mtime' => setv(T_NUMBER, 0, 1, 0, 0, undef), + 'atime' => setv(T_NUMBER, 0, 1, 0, 0, undef), + 'status' => setv(T_ANY, 0, 1, 0, '', undef), + 'min-interval' => setv(T_DELAY, 0, 0, 1, interval('30s'), 0), + 'max-interval' => setv(T_DELAY, 0, 0, 1, interval('25d'), 0), + 'min-error-interval' => setv(T_DELAY, 0, 0, 1, interval('5m'), 0), + 'warned-min-interval' => setv(T_ANY, 0, 1, 0, 0, undef), + 'warned-min-error-interval' => setv(T_ANY, 0, 1, 0, 0, undef), + }, ); my %services = ( 'dyndns1' => { @@ -638,6 +661,15 @@ my %services = ( $variables{'service-common-defaults'}, ), }, + 'woima' => { + 'updateable' => undef, + 'update' => \&nic_woima_update, + 'examples' => \&nic_woima_examples, + 'variables' => merge( + $variables{'woima-common-defaults'}, + $variables{'woima-service-common-defaults'}, + ), + }, ); $variables{'merged'} = merge($variables{'global-defaults'}, $variables{'service-common-defaults'}, @@ -4224,6 +4256,182 @@ sub nic_duckdns_update { } } +###################################################################### +## nic_woima_examples +###################################################################### +sub nic_woima_examples { + return < 'Bad authorization (username or password)', + 'badsys' => 'The system parameter given was not valid', + + 'notfqdn' => 'A Fully-Qualified Domain Name was not provided', + 'nohost' => 'The hostname specified does not exist in the database', + '!yours' => 'The hostname specified exists, but not under the username currently being used', + '!donator' => 'The offline setting was set, when the user is not a donator', + '!active' => 'The hostname specified is in a Custom DNS domain which has not yet been activated.', + 'abuse', => 'The hostname specified is blocked for abuse; you should receive an email notification ' . + 'which provides an unblock request link. More info can be found on ' . + 'https://www.dyndns.com/support/abuse.html', + + 'numhost' => 'System error: Too many or too few hosts found. Contact support@dyndns.org', + 'dnserr' => 'System error: DNS error encountered. Contact support@dyndns.org', + + 'nochg' => 'No update required; unnecessary attempts to change to the current address are considered abusive', + ); + + my @hosts = @_; + foreach my $key (keys @hosts) { + my $h = $hosts[$key]; + my $ip = $config{$h}{'wantip'}; + delete $config{$h}{'wantip'}; + + info("setting IP address to %s for %s", $ip, $h); + verbose("UPDATE:","updating %s", $h); + + ## Select the DynDNS system to update + my $url = "http://$config{$h}{'server'}$config{$h}{'script'}?system="; + if ($config{$h}{'custom'}) { + warning("updating %s: 'custom' and 'static' may not be used together. ('static' ignored)", $h) + if $config{$h}{'static'}; + # warning("updating %s: 'custom' and 'offline' may not be used together. ('offline' ignored)", $h) + # if $config{$h}{'offline'}; + $url .= 'custom'; + + } elsif ($config{$h}{'static'}) { + # warning("updating %s: 'static' and 'offline' may not be used together. ('offline' ignored)", $h) + # if $config{$h}{'offline'}; + $url .= 'statdns'; + + } else { + $url .= 'dyndns'; + } + + $url .= "&hostname=$h"; + $url .= "&myip="; + $url .= $ip if $ip; + + ## some args are not valid for a custom domain. + $url .= "&wildcard=ON" if ynu($config{$h}{'wildcard'}, 1, 0, 0); + if ($config{$h}{'mx'}) { + $url .= "&mx=$config{$h}{'mx'}"; + $url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO'); + } + + my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'}); + if (!defined($reply) || !$reply) { + failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'}); + last; + } + last if !header_ok($h, $reply); + + my @reply = split /\n/, $reply; + my $state = 'header'; + my $returnedip = $ip; + + foreach my $line (@reply) { + if ($state eq 'header') { + $state = 'body'; + + } elsif ($state eq 'body') { + $state = 'results' if $line eq ''; + + } elsif ($state =~ /^results/) { + $state = 'results2'; + + # bug #10: some dyndns providers does not return the IP so + # we can't use the returned IP + my ($status, $returnedip) = split / /, lc $line; + $ip = $returnedip if (not $ip); + #my $h = shift @hosts; + + $config{$h}{'status'} = $status; + if ($status eq 'good') { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + success("updating %s: %s: IP address set to %s", $h, $status, $ip); + + } elsif (exists $errors{$status}) { + if ($status eq 'nochg') { + warning("updating %s: %s: %s", $h, $status, $errors{$status}); + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + + } else { + failed("updating %s: %s: %s", $h, $status, $errors{$status}); + } + + } elsif ($status =~ /w(\d+)(.)/) { + my ($wait, $units) = ($1, lc $2); + my ($sec, $scale) = ($wait, 1); + + ($scale, $units) = (1, 'seconds') if $units eq 's'; + ($scale, $units) = (60, 'minutes') if $units eq 'm'; + ($scale, $units) = (60*60, 'hours') if $units eq 'h'; + + $sec = $wait * $scale; + $config{$h}{'wtime'} = $now + $sec; + warning("updating %s: %s: wait $wait $units before further updates", $h, $status, $ip); + + } else { + failed("updating %s: %s: unexpected status (%s)", $h, $line); + } + } + } + failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'}) + if $state ne 'results2'; + } +} + + ###################################################################### # vim: ai ts=4 sw=4 tw=78 : From 14e8539eaf9d632b604ab9982bced8bb4e89a297 Mon Sep 17 00:00:00 2001 From: Janne Hannila Date: Wed, 2 Sep 2015 18:51:30 +0300 Subject: [PATCH 25/36] Prevent service to start multiple times. Added messages if trying to start/stop already started/stopped service. Added daemon install instructions for ubuntu. --- README.md | 9 +++++++++ sample-etc_rc.d_init.d_ddclient.ubuntu | 20 +++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a83a1e1..f492f5f 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,15 @@ INSTALLATION: apk add perl ## start the first time by hand rc-service ddclient start + + ## For those using Ubuntu style rc files and using daemon-mode: + cp sample-etc_rc.d_init.d_ddclient.ubuntu /etc/init.d/ddclient + ## enable automatic startup when booting + update-rc.d ddclient defaults + ## make sure you have perl installed + apt-get install perl + ## start the first time by hand + service ddclient start ## If you are not using daemon-mode, configure cron and dhcp or ppp ## as described below. diff --git a/sample-etc_rc.d_init.d_ddclient.ubuntu b/sample-etc_rc.d_init.d_ddclient.ubuntu index 348ffd4..b2d6878 100755 --- a/sample-etc_rc.d_init.d_ddclient.ubuntu +++ b/sample-etc_rc.d_init.d_ddclient.ubuntu @@ -20,15 +20,19 @@ test -f $CONF || exit 0 case "$1" in start) - log_begin_msg "Starting ddclient..." - DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'` - if [ -z "$DELAY" ] ; then - DELAY="-daemon 300" + if [ ! -f $PIDFILE ]; then + log_begin_msg "Starting ddclient..." + DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'` + if [ -z "$DELAY" ] ; then + DELAY="-daemon 300" + else + DELAY='' + fi + start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY + log_end_msg $? else - DELAY='' + log_warning_msg "Service ddclient already running..." fi - start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY - log_end_msg $? ;; stop) if [ -f $PIDFILE ] ; then @@ -36,6 +40,8 @@ case "$1" in start-stop-daemon -K -q -p $PIDFILE log_end_msg $? rm -f $PIDFILE + else + log_warning_msg "No ddclient running..." fi ;; restart|reload|force-reload) From b478bf1a85a5060251e930a2b5cddf31b3e87f66 Mon Sep 17 00:00:00 2001 From: Erik Gregg Date: Sat, 28 Nov 2015 13:28:46 -0500 Subject: [PATCH 26/36] Don't issue warnings when freedns IP didn't change Before this update, freedns warnings would appear in the log even though FreeDNS sent back a code 200 with a message indicating the IP address was already correct. A simple regex change was all that was needed to make this a success instead. Now, it looks like this: DEBUG: server = freedns.afraid.org SUCCESS: updating xxx.xxx.xxx good: IP address has not changed Conflicts: ddclient --- README.md | 2 +- ddclient | 59 +++++++++++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 241b1a7..4560eeb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ =============================================================================== -# DDCLIENT v3.8.2 +# DDCLIENT v3.8.3 ddclient is a Perl client used to update dynamic DNS entries for accounts on many dynamic DNS services. diff --git a/ddclient b/ddclient index 7abb5dd..ef7ca8d 100755 --- a/ddclient +++ b/ddclient @@ -3704,10 +3704,7 @@ EoEXAMPLE ## ###################################################################### sub nic_freedns_update { - - debug("\nnic_freedns_update -------------------"); - ## First get the list of updatable hosts my $url; $url = "http://$config{$_[0]}{'server'}/api/?action=getdyndns&sha=".&sha1_hex("$config{$_[0]}{'login'}|$config{$_[0]}{'password'}"); @@ -3733,34 +3730,36 @@ sub nic_freedns_update { info("setting IP address to %s for %s", $ip, $h); verbose("UPDATE:","updating %s", $h); - if($ip eq $freedns_hosts{$h}->[1]) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("update not necessary %s: good: IP address already set to %s", $h, $ip); - } else { - my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]); - if (!defined($reply) || !$reply) { - failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]); - last; - } - if(!header_ok($h, $reply)) { - $config{$h}{'status'} = 'failed'; - last; - } + if($ip eq $freedns_hosts{$h}->[1]) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("update not necessary %s: good: IP address already set to %s", $h, $ip); + } else { + my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]); + if (!defined($reply) || !$reply) { + failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]); + last; + } + if(!header_ok($h, $reply)) { + $config{$h}{'status'} = 'failed'; + last; + } - if($reply =~ /Updated.*$h.*to.*$ip/) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("updating %s: good: IP address set to %s", $h, $ip); - } else { - $config{$h}{'status'} = 'failed'; - warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose'); - warning("REPLIED: %s", $reply); - failed("updating %s: Invalid reply.", $h); - } - } + if($reply =~ /Updated.*$h.*to.*$ip/) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("updating %s: good: IP address set to %s", $h, $ip); + } elsif ($reply =~ /Address .* has not changed/) { + success("updating %s: good: IP address has not changed", $h, $ip); + } else { + $config{$h}{'status'} = 'failed'; + warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose'); + warning("REPLIED: %s", $reply); + failed("updating %s: Invalid reply.", $h); + } + } } } From a2815d50812330939b63963cbd2c635ef0c68e34 Mon Sep 17 00:00:00 2001 From: Erik Gregg Date: Sat, 28 Nov 2015 13:51:27 -0500 Subject: [PATCH 27/36] Minor change to cache ip on freedns no-change --- ddclient | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/ddclient b/ddclient index ef7ca8d..d242e4f 100755 --- a/ddclient +++ b/ddclient @@ -3730,29 +3730,33 @@ sub nic_freedns_update { info("setting IP address to %s for %s", $ip, $h); verbose("UPDATE:","updating %s", $h); - if($ip eq $freedns_hosts{$h}->[1]) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("update not necessary %s: good: IP address already set to %s", $h, $ip); + if($ip eq $freedns_hosts{$h}->[1]) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("update not necessary %s: good: IP address already set to %s", $h, $ip); } else { my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]); if (!defined($reply) || !$reply) { failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]); last; } - if(!header_ok($h, $reply)) { - $config{$h}{'status'} = 'failed'; + if(!header_ok($h, $reply)) { + $config{$h}{'status'} = 'failed'; last; } - if($reply =~ /Updated.*$h.*to.*$ip/) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("updating %s: good: IP address set to %s", $h, $ip); - } elsif ($reply =~ /Address .* has not changed/) { - success("updating %s: good: IP address has not changed", $h, $ip); + if($reply =~ /Updated.*$h.*to.*$ip/) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("updating %s: good: IP address set to %s", $h, $ip); + } elsif ($reply =~ /Address (\d+\.\d+\.\d+\.\d+) has not changed/) { + $ip = $1; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + $config{$h}{'ip'} = $ip; + success("updating %s: good: IP address %s has not changed", $h, $ip); } else { $config{$h}{'status'} = 'failed'; warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose'); From 4f7fb1b3aadf446373bee8319cfefb77e6993e64 Mon Sep 17 00:00:00 2001 From: wimpunk Date: Thu, 3 Dec 2015 21:18:13 +0100 Subject: [PATCH 28/36] README: update version number. This change was suggested in pull request #31 on github by @hank. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 241b1a7..4560eeb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ =============================================================================== -# DDCLIENT v3.8.2 +# DDCLIENT v3.8.3 ddclient is a Perl client used to update dynamic DNS entries for accounts on many dynamic DNS services. From 5abb9fe1fe4a3212de461723e0727ff734cc27ec Mon Sep 17 00:00:00 2001 From: wimpunk Date: Thu, 3 Dec 2015 21:27:41 +0100 Subject: [PATCH 29/36] Fixing warnings on FreeDNS update NOP Fix based on pull request #31 on github commited by @hank. _original comments_ When FreeDNS was updating, I was noticing that it would send back an HTTP 200 with the text "Address [IP] has not changed", but ddclient was issuing a failed status for this and logging a ton of text to syslog. I changed the function a tiny bit to allow this to be a success status. I also reformatted the code to all spaces instead of mixed spaces and tabs, but you can take that or leave it - I don't really care, it was just a total whitespace disaster before. --- ddclient | 63 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/ddclient b/ddclient index 7abb5dd..c2e7ddd 100755 --- a/ddclient +++ b/ddclient @@ -3704,10 +3704,7 @@ EoEXAMPLE ## ###################################################################### sub nic_freedns_update { - - debug("\nnic_freedns_update -------------------"); - ## First get the list of updatable hosts my $url; $url = "http://$config{$_[0]}{'server'}/api/?action=getdyndns&sha=".&sha1_hex("$config{$_[0]}{'login'}|$config{$_[0]}{'password'}"); @@ -3733,34 +3730,40 @@ sub nic_freedns_update { info("setting IP address to %s for %s", $ip, $h); verbose("UPDATE:","updating %s", $h); - if($ip eq $freedns_hosts{$h}->[1]) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("update not necessary %s: good: IP address already set to %s", $h, $ip); - } else { - my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]); - if (!defined($reply) || !$reply) { - failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]); - last; - } - if(!header_ok($h, $reply)) { - $config{$h}{'status'} = 'failed'; - last; - } + if($ip eq $freedns_hosts{$h}->[1]) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("update not necessary %s: good: IP address already set to %s", $h, $ip); + } else { + my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]); + if (!defined($reply) || !$reply) { + failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]); + last; + } + if(!header_ok($h, $reply)) { + $config{$h}{'status'} = 'failed'; + last; + } - if($reply =~ /Updated.*$h.*to.*$ip/) { - $config{$h}{'ip'} = $ip; - $config{$h}{'mtime'} = $now; - $config{$h}{'status'} = 'good'; - success("updating %s: good: IP address set to %s", $h, $ip); - } else { - $config{$h}{'status'} = 'failed'; - warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose'); - warning("REPLIED: %s", $reply); - failed("updating %s: Invalid reply.", $h); - } - } + if ($reply =~ /Updated.*$h.*to.*$ip/) { + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("updating %s: good: IP address set to %s", $h, $ip); + } elsif ($reply =~ /Address (\d+\.\d+\.\d+\.\d+) has not changed/) { + $ip = $1; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + $config{$h}{'ip'} = $ip; + success("updating %s: good: IP address %s has not changed", $h, $ip); + } else { + $config{$h}{'status'} = 'failed'; + warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose'); + warning("REPLIED: %s", $reply); + failed("updating %s: Invalid reply.", $h); + } + } } } From 027fa03895f9cbeec87d1c68237ab21cefedd49a Mon Sep 17 00:00:00 2001 From: Gerald Hansen Date: Mon, 18 Jan 2016 12:30:07 +0100 Subject: [PATCH 30/36] add ipv6 support for web option --- ddclient | 49 +++++++++++++++++++++++++++++++++++----- sample-etc_ddclient.conf | 9 ++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ddclient b/ddclient index a2805e8..502033f 100755 --- a/ddclient +++ b/ddclient @@ -903,8 +903,10 @@ sub update_nics { next; } if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { - warning("malformed IP address (%s)", $ip); - next; + if( !ipv6_match($ip) ) { + warning("malformed IP address (%s)", $ip); + next; + } } $iplist{$use}{$arg_ip}{$arg_fw}{$arg_if}{$arg_web}{$arg_cmd} = $ip; } @@ -1850,7 +1852,9 @@ sub check_value { # return undef if $value =~ /:/; } elsif ($type eq T_IP) { - return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; + if( !ipv6_match($value) ) { + return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; + } } return $value; } @@ -2192,9 +2196,14 @@ sub get_ip { $reply =~ s/^.*?${skip}//is; } if ($reply =~ /^.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b.*/is) { - $ip = $1; - $ip = un_zero_pad($ip); - $ip = filter_local($ip) if opt('fw-banlocal', $h); + $ip = $1; + $ip = un_zero_pad($ip); + $ip = filter_local($ip) if opt('fw-banlocal', $h); + } elsif ( $ip = ipv6_match($reply) ) { + $ip = un_zero_pad($ip); + $ip = filter_local($ip) if opt('fw-banlocal', $h); + } else { + warning("found neither ipv4 nor ipv6 address"); } if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) { $ip = undef; @@ -2204,6 +2213,34 @@ sub get_ip { return $ip; } +###################################################################### +## ipv6_match determine ipv6 address from given string and return them +###################################################################### +sub ipv6_match { + my $content = shift; + my $omits; + my $ip = ""; + my $linenumbers = 0; + + my @values = split('\n', $content); + foreach my $val (@values) { + next unless $val =~ /((:{0,2}[A-F0-9]{1,4}){0,7}:{1,2}[A-F0-9]{1,4})/ai; # invalid char + my $parsed = $1; + + # check for at least 7 colons + my $count_colon = () = $parsed =~ /:/g; + if ($count_colon != 7) { + # or one double colon + my $count_double_colon = () = $parsed =~ /::/g; + if ($count_double_colon != 1) { + next + } + } + return $parsed; + } + return; +} + ###################################################################### ## group_hosts_by ###################################################################### diff --git a/sample-etc_ddclient.conf b/sample-etc_ddclient.conf index 79a7130..d1e1761 100644 --- a/sample-etc_ddclient.conf +++ b/sample-etc_ddclient.conf @@ -221,3 +221,12 @@ ssl=yes # use ssl-support. Works with # password=my-auto-generated-password # protocol=duckdns hostwithoutduckdnsorg +## +## MyOnlinePortal (http://myonlineportal.net) +## +# protocol=dyndns2 +# ssl=yes +# use=web, web=myonlineportal.net/checkip +# login=your-myonlineportal-username +# password=your-myonlineportal-password +# domain.myonlineportal.net From dc01f09224a17f493a43a219cd9a71c96c5054ee Mon Sep 17 00:00:00 2001 From: Gerald Hansen Date: Mon, 18 Jan 2016 22:31:12 +0100 Subject: [PATCH 31/36] add ipv6 support --- README.md | 7 +-- ddclient | 153 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 4560eeb..8fa84d5 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Dynamic DNS services currently supported include: nsupdate - See nsupdate(1) and ddns-confgen(8) for details CloudFlare - See https://www.cloudflare.com/ for details Google - See http://www.google.com/domains for details - Duckdns - See https://duckdns.org/ for details + Duckdns - See https://duckdns.org/ for details woima.fi - See https://woima.fi/ for details DDclient now supports many of cable/dsl broadband routers. @@ -42,8 +42,9 @@ REQUIREMENTS: - one or more accounts from one of the dynamic DNS services - Perl 5.014 or later - (you need the IO::Socket::SSL perl library for ssl-support - and JSON::Any perl library for JSON support) + (you need the IO::Socket::SSL perl library for ssl-support, + JSON::Any perl library for JSON support and + IO::Socket:INET6 perl library for ipv6-support) - Linux or probably any common Unix system diff --git a/ddclient b/ddclient index 502033f..c9a7d71 100755 --- a/ddclient +++ b/ddclient @@ -345,12 +345,12 @@ my %variables = ( 'retry' => setv(T_BOOL, 0, 0, 0, 0, undef), 'force' => setv(T_BOOL, 0, 0, 0, 0, undef), 'ssl' => setv(T_BOOL, 0, 0, 0, 0, undef), - + 'ipv6' => setv(T_BOOL, 0, 0, 0, 0, undef), 'syslog' => setv(T_BOOL, 0, 0, 1, 0, undef), 'facility' => setv(T_STRING,0, 0, 1, 'daemon', undef), 'priority' => setv(T_STRING,0, 0, 1, 'notice', undef), - 'mail' => setv(T_EMAIL, 0, 0, 1, '', undef), - 'mail-failure' => setv(T_EMAIL, 0, 0, 1, '', undef), + 'mail' => setv(T_EMAIL, 0, 0, 1, '', undef), + 'mail-failure' => setv(T_EMAIL, 0, 0, 1, '', undef), 'exec' => setv(T_BOOL, 0, 0, 1, 1, undef), 'debug' => setv(T_BOOL, 0, 0, 1, 0, undef), @@ -380,7 +380,7 @@ my %variables = ( 'fw-password' => setv(T_PASSWD,0, 0, 1, '', undef), 'cmd' => setv(T_PROG, 0, 0, 1, '', undef), 'cmd-skip' => setv(T_STRING,0, 0, 1, '', undef), - + 'ipv6' => setv(T_BOOL, 0, 0, 0, 0, undef), 'ip' => setv(T_IP, 0, 1, 0, undef, undef), 'wtime' => setv(T_DELAY, 0, 1, 1, 0, interval('30s')), 'mtime' => setv(T_NUMBER, 0, 1, 0, 0, undef), @@ -681,7 +681,7 @@ my @opt = ( "usage: ${program} [options]", "options are:", [ "daemon", "=s", "-daemon delay : run as a daemon, specify delay as an interval." ], - [ "foreground", "!", "-foreground : do not fork" ], + [ "foreground", "!", "-foreground : do not fork" ], [ "proxy", "=s", "-proxy host : use 'host' as the HTTP proxy" ], [ "server", "=s", "-server host : update DNS information on 'host'" ], [ "protocol", "=s", "-protocol type : update protocol used" ], @@ -729,6 +729,7 @@ my @opt = ( [ "debug", "!", "-{no}debug : print {no} debugging information" ], [ "verbose", "!", "-{no}verbose : print {no} verbose information" ], [ "quiet", "!", "-{no}quiet : print {no} messages for unnecessary updates" ], + [ "ipv6", "!", "-{no}ipv6 : use ipv6" ], [ "help", "", "-help : this message" ], [ "postscript", "", "-postscript : script to run after updating ddclient, has new IP as param" ], @@ -1048,7 +1049,7 @@ sub parse_assignment { my ($c, $name, $value); my ($escape, $quote) = (0, ''); - if ($rest =~ /^\s*([a-z][a-z_-]*)=(.*)/i) { + if ($rest =~ /^\s*([a-z][0-9a-z_-]*)=(.*)/i) { ($name, $rest, $value) = ($1, $2, ''); while (length($c = substr($rest,0,1))) { @@ -1161,7 +1162,7 @@ sub _read_config { ## verify that keywords are valid...and check the value foreach my $k (keys %locals) { - $locals{$k} = $passwords{$k} if defined $passwords{$k}; + $locals{$k} = $passwords{$k} if defined $passwords{$k}; if (!exists $variables{'merged'}{$k}) { warning("unrecognized keyword '%s' (ignored)", $k); delete $locals{$k}; @@ -1258,14 +1259,14 @@ sub init_config { ## and those in -options=... if (exists $options{'host'}) { foreach my $h (split_by_comma($options{'host'})) { - push @hosts, $h; + push @hosts, $h; } delete $options{'host'}; } ## merge options into host definitions or globals if (@hosts) { foreach my $h (@hosts) { - $config{$h} = merge(\%options, $config{$h}); + $config{$h} = merge(\%options, $config{$h}); } $opt{'host'} = join(',', @hosts); } else { @@ -1275,14 +1276,14 @@ sub init_config { ## override global options with those on the command-line. foreach my $o (keys %opt) { - if (defined $opt{$o} && exists $variables{'global-defaults'}{$o}) { - $globals{$o} = $opt{$o}; - } + if (defined $opt{$o} && exists $variables{'global-defaults'}{$o}) { + $globals{$o} = $opt{$o}; + } } ## sanity check if (defined $opt{'host'} && defined $opt{'retry'}) { - usage("options -retry and -host (or -option host=..) are mutually exclusive"); + usage("options -retry and -host (or -option host=..) are mutually exclusive"); } ## determine hosts to update (those on the cmd-line, config-file, or failed cached) @@ -1312,14 +1313,14 @@ sub init_config { ## make sure config entries have all defaults and they meet minimums ## first the globals... foreach my $k (keys %globals) { - my $def = $variables{'merged'}{$k}; - my $ovalue = define($globals{$k}, $def->{'default'}); - my $value = check_value($ovalue, $def); - if ($def->{'required'} && !defined $value) { - $value = default($k); - warning("'%s=%s' is an invalid %s. (using default of %s)", $k, $ovalue, $def->{'type'}, $value); - } - $globals{$k} = $value; + my $def = $variables{'merged'}{$k}; + my $ovalue = define($globals{$k}, $def->{'default'}); + my $value = check_value($ovalue, $def); + if ($def->{'required'} && !defined $value) { + $value = default($k); + warning("'%s=%s' is an invalid %s. (using default of %s)", $k, $ovalue, $def->{'type'}, $value); + } + $globals{$k} = $value; } ## now the host definitions... @@ -1893,6 +1894,24 @@ EOM import IO::Socket::SSL; { no warnings; $IO::Socket::SSL::DEBUG = 0; } } + +###################################################################### +## load_ipv6_support +###################################################################### +sub load_ipv6_support { + my $ipv6_loaded = eval {require IO::Socket::INET6}; + unless ($ipv6_loaded) { + fatal(<<"EOM"); +Error loading the Perl module IO::Socket::INET6 needed for ipv6 connect. +On Debian, the package libio-socket-ssl-perl must be installed. +On Red Hat, the package perl-IO-Socket-SSL must be installed. +On Alpine, the package perl-io-socket-ssl must be installed. +EOM + } + import IO::Socket::INET6; + { no warnings; $IO::Socket::INET6::DEBUG = 0; } +} + ###################################################################### ## load_sha1_support ###################################################################### @@ -1988,8 +2007,8 @@ sub geturl { # local $^W = 0; $0 = sprintf("%s - connecting to %s port %s", $program, $peer, $port); if (! opt('exec')) { - debug("skipped network connection"); - verbose("SENDING:", "%s", $request); + debug("skipped network connection"); + verbose("SENDING:", "%s", $request); } elsif ($use_ssl) { $sd = IO::Socket::SSL->new( PeerAddr => $peer, @@ -1999,6 +2018,16 @@ sub geturl { Timeout => opt('timeout'), ); defined $sd or warning("cannot connect to $peer:$port socket: $@ " . IO::Socket::SSL::errstr()); + } elsif ($globals{'ipv6'}) { + load_ipv6_support; + $sd = IO::Socket::INET6->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => 'tcp', + MultiHomed => 1, + Timeout => opt('timeout'), + ); + defined $sd or warning("cannot connect to $peer:$port socket: $@"); } else { $sd = IO::Socket::INET->new( PeerAddr => $peer, @@ -2141,63 +2170,63 @@ sub get_ip { } } elsif (($use eq 'cisco')) { - # Stuff added to support Cisco router ip http daemon - # User fw-login should only have level 1 access to prevent - # password theft. This is pretty harmless. - my $queryif = opt('if', $h); - $skip = opt('fw-skip', $h) || ''; + # Stuff added to support Cisco router ip http daemon + # User fw-login should only have level 1 access to prevent + # password theft. This is pretty harmless. + my $queryif = opt('if', $h); + $skip = opt('fw-skip', $h) || ''; - # Convert slashes to protected value "\/" - $queryif =~ s%\/%\\\/%g; + # Convert slashes to protected value "\/" + $queryif =~ s%\/%\\\/%g; - # Protect special HTML characters (like '?') - $queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge; + # Protect special HTML characters (like '?') + $queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge; - $url = "http://".opt('fw', $h)."/level/1/exec/show/ip/interface/brief/${queryif}/CR"; - $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; - $arg = $url; + $url = "http://".opt('fw', $h)."/level/1/exec/show/ip/interface/brief/${queryif}/CR"; + $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; + $arg = $url; } elsif (($use eq 'cisco-asa')) { - # Stuff added to support Cisco ASA ip https daemon - # User fw-login should only have level 1 access to prevent - # password theft. This is pretty harmless. - my $queryif = opt('if', $h); - $skip = opt('fw-skip', $h) || ''; + # Stuff added to support Cisco ASA ip https daemon + # User fw-login should only have level 1 access to prevent + # password theft. This is pretty harmless. + my $queryif = opt('if', $h); + $skip = opt('fw-skip', $h) || ''; - # Convert slashes to protected value "\/" - $queryif =~ s%\/%\\\/%g; + # Convert slashes to protected value "\/" + $queryif =~ s%\/%\\\/%g; - # Protect special HTML characters (like '?') - $queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge; + # Protect special HTML characters (like '?') + $queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge; - $url = "https://".opt('fw', $h)."/exec/show%20interface%20${queryif}"; - $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; - $arg = $url; + $url = "https://".opt('fw', $h)."/exec/show%20interface%20${queryif}"; + $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; + $arg = $url; } else { - $url = opt('fw', $h) || ''; - $skip = opt('fw-skip', $h) || ''; + $url = opt('fw', $h) || ''; + $skip = opt('fw-skip', $h) || ''; - if (exists $builtinfw{$use}) { - $skip = $builtinfw{$use}->{'skip'} unless $skip; - $url = "http://${url}" . $builtinfw{$use}->{'url'} unless $url =~ /\//; - } - $arg = $url; + if (exists $builtinfw{$use}) { + $skip = $builtinfw{$use}->{'skip'} unless $skip; + $url = "http://${url}" . $builtinfw{$use}->{'url'} unless $url =~ /\//; + } + $arg = $url; - if ($url) { - $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; + if ($url) { + $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; + } } - } - if (!defined $reply) { - $reply = ''; + if (!defined $reply) { + $reply = ''; } if ($skip) { - $skip =~ s/ /\\s/is; - $reply =~ s/^.*?${skip}//is; + $skip =~ s/ /\\s/is; + $reply =~ s/^.*?${skip}//is; } if ($reply =~ /^.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b.*/is) { $ip = $1; - $ip = un_zero_pad($ip); + $ip = un_zero_pad($ip); $ip = filter_local($ip) if opt('fw-banlocal', $h); } elsif ( $ip = ipv6_match($reply) ) { $ip = un_zero_pad($ip); From 3c2ef3e24cab34bc2b4479cb4865b3853eeae38a Mon Sep 17 00:00:00 2001 From: Gerald Hansen Date: Mon, 18 Jan 2016 22:43:26 +0100 Subject: [PATCH 32/36] add ipv6 sample config for myonlineportal.net --- sample-etc_ddclient.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sample-etc_ddclient.conf b/sample-etc_ddclient.conf index d1e1761..8ef3fbe 100644 --- a/sample-etc_ddclient.conf +++ b/sample-etc_ddclient.conf @@ -226,7 +226,10 @@ ssl=yes # use ssl-support. Works with ## # protocol=dyndns2 # ssl=yes +# # ipv6=yes # optional # use=web, web=myonlineportal.net/checkip +# # use=if, if=eth0 # alternative to use=web +# # if-skip=Scope:Link # alternative to use=web # login=your-myonlineportal-username # password=your-myonlineportal-password # domain.myonlineportal.net From 9ba67ab9f8446afb964dc74a724167af87bf6ed0 Mon Sep 17 00:00:00 2001 From: Gerald Hansen Date: Tue, 19 Jan 2016 10:37:08 +0100 Subject: [PATCH 33/36] fix description for missing package --- ddclient | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ddclient b/ddclient index c9a7d71..331d7f9 100755 --- a/ddclient +++ b/ddclient @@ -1903,9 +1903,9 @@ sub load_ipv6_support { unless ($ipv6_loaded) { fatal(<<"EOM"); Error loading the Perl module IO::Socket::INET6 needed for ipv6 connect. -On Debian, the package libio-socket-ssl-perl must be installed. -On Red Hat, the package perl-IO-Socket-SSL must be installed. -On Alpine, the package perl-io-socket-ssl must be installed. +On Debian, the package libio-socket-inet6-perl must be installed. +On Red Hat, the package perl-IO-Socket-INET6 must be installed. +On Alpine, the package perl-io-socket-inet6 must be installed. EOM } import IO::Socket::INET6; From 6b7942a139a4e11461fd2e98777d1c91a0a8a882 Mon Sep 17 00:00:00 2001 From: wimpunk Date: Mon, 25 Jan 2016 21:40:18 +0100 Subject: [PATCH 34/36] README: fixing duckdns identation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4560eeb..068c5bd 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Dynamic DNS services currently supported include: nsupdate - See nsupdate(1) and ddns-confgen(8) for details CloudFlare - See https://www.cloudflare.com/ for details Google - See http://www.google.com/domains for details - Duckdns - See https://duckdns.org/ for details + Duckdns - See https://duckdns.org/ for details woima.fi - See https://woima.fi/ for details DDclient now supports many of cable/dsl broadband routers. From 375d075a3c1bc81e4acdf83fa137ec76046f3ee6 Mon Sep 17 00:00:00 2001 From: Nick Williams Date: Tue, 26 Jan 2016 10:42:22 -0600 Subject: [PATCH 35/36] Add support for telling `nsupdate` to use TCP instead of UDP By default, `nsupdate` uses UDP unless the update size is too large to fit in a UDP datagram, in which case it automatically switches to TCP. This change adds a `tcp` configuration option to the `nsupdate` protocol so that the user can force `nsupdate` to use TCP. --- ddclient | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ddclient b/ddclient index 331d7f9..83e28ca 100755 --- a/ddclient +++ b/ddclient @@ -437,6 +437,7 @@ my %variables = ( 'nsupdate-common-defaults' => { 'ttl' => setv(T_NUMBER, 0, 1, 0, 600, undef), 'zone' => setv(T_STRING, 1, 1, 1, '', undef), + 'tcp' => setv(T_BOOL, 0, 1, 1, 0, undef), }, 'cloudflare-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef), @@ -4091,6 +4092,10 @@ Configuration variables applicable to the 'nsupdate' protocol are: zone=dyn.example.com ## forward zone that is to be updated ttl=600 ## time to live of the record; ## defaults to 600 seconds + tcp=off|on ## nsupdate uses UDP by default, and switches to + ## TCP if the update is too large to fit in a + ## UDP datagram; this setting forces TCP; + ## defaults to off login=/usr/bin/nsupdate ## path and name of nsupdate binary; ## defaults to '/usr/bin/nsupdate' ## fully qualified hostname to update @@ -4147,6 +4152,7 @@ EoINSTR2 send EoINSTR3 my $command = "$binary -k $keyfile"; + $command .= " -v" if ynu($config{$h}{'tcp'}, 1, 0, 0); $command .= " -d" if (opt('debug')); verbose("UPDATE:", "nsupdate command is: %s", $command); verbose("UPDATE:", "nsupdate instructions are:\n%s", $instructions); From 62c6460784b9bb738f3a7e289302e8573320954c Mon Sep 17 00:00:00 2001 From: Michael Harder Date: Thu, 4 Feb 2016 01:06:17 -0800 Subject: [PATCH 36/36] fix nsupdate using wrong type for ipv6 addresses --- ddclient | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ddclient b/ddclient index 83e28ca..8eda1c5 100755 --- a/ddclient +++ b/ddclient @@ -24,6 +24,7 @@ use strict; use Getopt::Long; use Sys::Hostname; use IO::Socket; +use Data::Validate::IP; my $version = "3.8.3"; my $programd = $0; @@ -4132,6 +4133,12 @@ sub nic_nsupdate_update { my $server = $config{$h}{'server'}; my $zone = $config{$h}{'zone'}; my $ip = $config{$h}{'wantip'}; + my $recordtype = ''; + if (is_ipv6($ip)) { + $recordtype = 'AAAA'; + } else { + $recordtype = 'A'; + } delete $config{$_}{'wantip'} foreach @hosts; info("setting IP address to %s for %s", $ip, $hosts); @@ -4144,8 +4151,8 @@ zone $zone. EoINSTR1 foreach (@hosts) { $instructions .= <