Commit a11b90b7218e1e2d218da307554a5bd99eaca2f9

Authored by Frederik Lindenaar
1 parent f6637881

small improvements + configurable DNSDomain

- fixed handling of expiry
- fixed calculation of expiry period
- reduced CNAME checks / lookups to when really needed
Showing 2 changed files with 45 additions and 19 deletions
dyndns.cfg.dist
@@ -6,6 +6,14 @@ @@ -6,6 +6,14 @@
6 # DNS Settings 6 # DNS Settings
7 #dns_server = 192.168.1.1 # DNS Server to communicate with (use IP!) 7 #dns_server = 192.168.1.1 # DNS Server to communicate with (use IP!)
8 8
  9 +dns_domain = ?, !, 1 # DNS Domain to support, match hostname with:
  10 + # '?' - take domain name from parameter 'domain'
  11 + # '!' - take domain name from virtualhost name
  12 + # positive number - last # parts from hostname
  13 + # negative number - last # parts from virtualhost
  14 + # any other string - use if hostname ends on this
  15 +
  16 +
9 #expand_cnames = 1 # CNAME levels to expand (0 to disable) 17 #expand_cnames = 1 # CNAME levels to expand (0 to disable)
10 #require_rr = # Require existing record of this type to update 18 #require_rr = # Require existing record of this type to update
11 #replace_rr = A, AAAA, TXT # Records types to replace (clear) during update 19 #replace_rr = A, AAAA, TXT # Records types to replace (clear) during update
dyndns.pl
@@ -31,6 +31,12 @@ my $ConfigFile = 'optional'; # hardcoded, either optional, required or ignore @@ -31,6 +31,12 @@ my $ConfigFile = 'optional'; # hardcoded, either optional, required or ignore
31 ############################## 31 ##############################
32 # Configuration section (defaults, can be set in config file) 32 # Configuration section (defaults, can be set in config file)
33 my $DNSServer = '192.168.1.1'; # DNS Server to communicate with (use IP!) 33 my $DNSServer = '192.168.1.1'; # DNS Server to communicate with (use IP!)
  34 +my @DNSDomain = ( '?', '!', 0 ); # DNS Domain to support, matches hostname with:
  35 + # '?' - take domain name from parameter 'domain'
  36 + # '!' - take domain name from virtualhost name
  37 + # positive number - last # parts from hostname
  38 + # negative number - last # parts from virtualhost
  39 + # any other string - use if hostname ends on this
34 my $ExpandCNAMEs = 1; # CNAME levels to expand (0 to disable) 40 my $ExpandCNAMEs = 1; # CNAME levels to expand (0 to disable)
35 my $AllowDebugKey = 'off'; # Debuging, 'off' to disable, '' for always on 41 my $AllowDebugKey = 'off'; # Debuging, 'off' to disable, '' for always on
36 # and other values to enable with debug= param. 42 # and other values to enable with debug= param.
@@ -63,8 +69,8 @@ sub periodSeconds($) { @@ -63,8 +69,8 @@ sub periodSeconds($) {
63 my ($number, $units) = ($_[0]=~/^(\d+)([smhdw])?$/); 69 my ($number, $units) = ($_[0]=~/^(\d+)([smhdw])?$/);
64 if($number && $units && $units cmp 's') { 70 if($number && $units && $units cmp 's') {
65 $number *= ($units eq 'm') ? 60 # Seconds per minute 71 $number *= ($units eq 'm') ? 60 # Seconds per minute
66 - : ($units cmp 'h') ? 3600 # Seconds per hour  
67 - : ($units cmp 'd') ? 86400 # Seconds per day 72 + : ($units eq 'h') ? 3600 # Seconds per hour
  73 + : ($units eq 'd') ? 86400 # Seconds per day
68 : 604800; # Seconds per week 74 : 604800; # Seconds per week
69 } 75 }
70 return $number; 76 return $number;
@@ -222,8 +228,9 @@ sub DNS_Update($$$$$$$) { @@ -222,8 +228,9 @@ sub DNS_Update($$$$$$$) {
222 228
223 ############################## 229 ##############################
224 # Handlers for the different requests 230 # Handlers for the different requests
225 -sub handle_update($$$$$) {  
226 - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; 231 +sub handle_update($$$$) {
  232 + my ($mode, $host, $dnsdomain, $debug) = @_;
  233 + my $dnshost = expand_CNAME($host);
227 my ($signer, $key) = get_authinfo($cgi, $host); 234 my ($signer, $key) = get_authinfo($cgi, $host);
228 235
229 # perform the action 236 # perform the action
@@ -251,8 +258,8 @@ sub handle_update($$$$$) { @@ -251,8 +258,8 @@ sub handle_update($$$$$) {
251 258
252 } 259 }
253 260
254 -sub handle_expire($$$$$) {  
255 - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; 261 +sub handle_expire($$$$) {
  262 + my ($mode, $host, $dnsdomain, $debug) = @_;
256 my ($signer, $key) = get_authinfo($cgi, $host); 263 my ($signer, $key) = get_authinfo($cgi, $host);
257 264
258 my $debugmsg = ($debug) ? "\n" : ''; 265 my $debugmsg = ($debug) ? "\n" : '';
@@ -269,7 +276,7 @@ sub handle_expire($$$$$) { @@ -269,7 +276,7 @@ sub handle_expire($$$$$) {
269 if($rr->type eq 'TXT' && 276 if($rr->type eq 'TXT' &&
270 $rr->txtdata=~/$UpdateTXT(.*\d\d:\d\d:\d\d \d{4})$/){ 277 $rr->txtdata=~/$UpdateTXT(.*\d\d:\d\d:\d\d \d{4})$/){
271 if(my $lastupdate = parse_localtime($1)) { 278 if(my $lastupdate = parse_localtime($1)) {
272 - DNS_Update($dnsdomain, $dnshost, undef, undef, $signer, $key, $debug) 279 + DNS_Update($dnsdomain, $rr->name, undef, undef, $signer, $key, $debug)
273 unless($lastupdate > $validafter); 280 unless($lastupdate > $validafter);
274 if($debug) { 281 if($debug) {
275 $debugmsg .= ($lastupdate > $validafter) ? 'Keeping ' : 'Expiring '; 282 $debugmsg .= ($lastupdate > $validafter) ? 'Keeping ' : 'Expiring ';
@@ -286,8 +293,9 @@ sub handle_expire($$$$$) { @@ -286,8 +293,9 @@ sub handle_expire($$$$$) {
286 } 293 }
287 } 294 }
288 295
289 -sub handle_view($$$$$) {  
290 - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; 296 +sub handle_view($$$$) {
  297 + my ($mode, $host, $dnsdomain, $debug) = @_;
  298 + my $dnshost = expand_CNAME($host);
291 my $title = "DynDNS Updater - $host"; 299 my $title = "DynDNS Updater - $host";
292 print $cgi->header(-status=>200), 300 print $cgi->header(-status=>200),
293 $cgi->start_html(-title => $title), 301 $cgi->start_html(-title => $title),
@@ -310,8 +318,8 @@ sub handle_view($$$$$) { @@ -310,8 +318,8 @@ sub handle_view($$$$$) {
310 print $cgi->end_html(); 318 print $cgi->end_html();
311 } 319 }
312 320
313 -sub handle_list($$$$$) {  
314 - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; 321 +sub handle_list($$$$) {
  322 + my ($mode, $host, $dnsdomain, $debug) = @_;
315 my $title = "DynDNS Updater - $dnsdomain"; 323 my $title = "DynDNS Updater - $dnsdomain";
316 324
317 print $cgi->header(-status=>200), 325 print $cgi->header(-status=>200),
@@ -345,7 +353,8 @@ if ($ConfigFile cmp 'ignore') { @@ -345,7 +353,8 @@ if ($ConfigFile cmp 'ignore') {
345 $CFGFile =~ s/(\.pl)?$/.cfg/; 353 $CFGFile =~ s/(\.pl)?$/.cfg/;
346 if (open (CONFIG, $CFGFile)) { 354 if (open (CONFIG, $CFGFile)) {
347 my %CONFIG = ( 355 my %CONFIG = (
348 - allow_debug_key => \$AllowDebugKey, dns_server => \$DNSServer, 356 + allow_debug_key => \$AllowDebugKey,
  357 + dns_server => \$DNSServer, dns_domain => \@DNSDomain,
349 expand_cnames => \$ExpandCNAMEs, auth_mode => \$AuthMode, 358 expand_cnames => \$ExpandCNAMEs, auth_mode => \$AuthMode,
350 static_signer => \$StaticSigner, static_key => \$StaticKey, 359 static_signer => \$StaticSigner, static_key => \$StaticKey,
351 require_rr => \$RequireRR, replace_rr => \@ReplaceRR, 360 require_rr => \$RequireRR, replace_rr => \@ReplaceRR,
@@ -399,6 +408,20 @@ foreach my $rrtype (@ReplaceRR) { @@ -399,6 +408,20 @@ foreach my $rrtype (@ReplaceRR) {
399 my $mode = $cgi->path_info || $cgi->param('mode') || 'view'; 408 my $mode = $cgi->path_info || $cgi->param('mode') || 'view';
400 $mode=~s/^\/([^\/]+)(\/(.*))?/$1/; 409 $mode=~s/^\/([^\/]+)(\/(.*))?/$1/;
401 my $host = $cgi->param('host') || $3; 410 my $host = $cgi->param('host') || $3;
  411 +my $dnsdomain;
  412 +foreach my $d (@DNSDomain) {
  413 + if ($d eq '!') { $d = $cgi->virtual_host; }
  414 + elsif ($d eq '?') { $d = $cgi->param('domain'); }
  415 + elsif ($d =~ /-?\d+/) {
  416 + if ($d <0) { $d = join('.', splice([ split(/\./, $cgi->virtual_host) ], $d)); }
  417 + else { $d = join('.', splice([ split(/\./, $host) ], ($d) ? -$d : 1)); }
  418 + }
  419 + $dnsdomain = $d if ($host && length($host) == length($d)+rindex($host,$d));
  420 + last if $dnsdomain;
  421 +}
  422 +fail($PE, "No host name to act on specified", 400)
  423 + unless $host || $mode eq 'list' || $mode eq 'expire';
  424 +fail($PE, "No host or domain name to act on specified", 400) unless $dnsdomain;
402 425
403 426
404 ############################## 427 ##############################
@@ -410,13 +433,8 @@ my %handlers = ( @@ -410,13 +433,8 @@ my %handlers = (
410 list => \&handle_list, 433 list => \&handle_list,
411 expire => \&handle_expire, 434 expire => \&handle_expire,
412 ); 435 );
413 -if($host eq '' and $mode cmp 'list' and $mode cmp 'expire') {  
414 - fail($PE, "No host name to act on specified", 400);  
415 -} elsif(my $handler = $handlers{$mode}) {  
416 - # Replace provided host with that of a CNAME it points to and determine domain  
417 - my $dnshost = ($host) ? expand_CNAME($host) : undef;  
418 - my $dnsdomain = $cgi->param('domain') || ($dnshost=~/\.(.*)$/)[0];  
419 - $handler->($mode, $host, $dnshost, $dnsdomain, $debug); 436 +if(my $handler = $handlers{$mode}) {
  437 + $handler->($mode, $host, $dnsdomain, $debug);
420 } else { 438 } else {
421 fail("File Not Found", "Invalid Mode '$mode' specified", 404); 439 fail("File Not Found", "Invalid Mode '$mode' specified", 404);
422 } 440 }