diff --git a/dyndns.cfg.dist b/dyndns.cfg.dist
index bcb9446..955be56 100644
--- a/dyndns.cfg.dist
+++ b/dyndns.cfg.dist
@@ -6,6 +6,14 @@
 # DNS Settings
 #dns_server = 192.168.1.1       # DNS Server to communicate with (use IP!)
 
+dns_domain = ?, !, 1 		# DNS Domain to support, match hostname with:
+				# '?' - take domain name from parameter 'domain'
+				# '!' - take domain name from virtualhost name
+				# positive number - last # parts from hostname
+				# negative number - last # parts from virtualhost
+				# any other string - use if hostname ends on this
+
+
 #expand_cnames = 1              # CNAME levels to expand (0 to disable)
 #require_rr =		        # Require existing record of this type to update
 #replace_rr = A, AAAA, TXT	# Records types to replace (clear) during update
diff --git a/dyndns.pl b/dyndns.pl
index a3e83b3..c0971dd 100755
--- a/dyndns.pl
+++ b/dyndns.pl
@@ -31,6 +31,12 @@ my $ConfigFile = 'optional';    # hardcoded, either optional, required or ignore
 ##############################
 # Configuration section (defaults, can be set in config file)
 my $DNSServer = '192.168.1.1';	# DNS Server to communicate with (use IP!)
+my @DNSDomain = ( '?', '!', 0 ); # DNS Domain to support, matches hostname with:
+                                # '?' - take domain name from parameter 'domain'
+                                # '!' - take domain name from virtualhost name
+                                # positive number - last # parts from hostname
+                                # negative number - last # parts from virtualhost
+                                # any other string - use if hostname ends on this
 my $ExpandCNAMEs = 1;		# CNAME levels to expand (0 to disable)
 my $AllowDebugKey = 'off';	# Debuging, 'off' to disable, '' for always on
 				# and other values to enable with debug= param.
@@ -63,8 +69,8 @@ sub periodSeconds($) {
   my ($number, $units) = ($_[0]=~/^(\d+)([smhdw])?$/);
   if($number && $units && $units cmp 's') {
       $number *= ($units eq 'm') ? 60		# Seconds per minute
-		: ($units cmp 'h') ? 3600	# Seconds per hour
-		: ($units cmp 'd') ? 86400	# Seconds per day
+		: ($units eq 'h') ? 3600	# Seconds per hour
+		: ($units eq 'd') ? 86400	# Seconds per day
 		: 604800;			# Seconds per week
   }
   return $number;
@@ -222,8 +228,9 @@ sub DNS_Update($$$$$$$) {
 
 ##############################
 # Handlers for the different requests
-sub handle_update($$$$$) {
-  my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_;
+sub handle_update($$$$) {
+  my ($mode, $host, $dnsdomain, $debug) = @_;
+  my $dnshost = expand_CNAME($host);
   my ($signer, $key) = get_authinfo($cgi, $host);
 
   # perform the action
@@ -251,8 +258,8 @@ sub handle_update($$$$$) {
 
 }
 
-sub handle_expire($$$$$) {
-  my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_;
+sub handle_expire($$$$) {
+  my ($mode, $host, $dnsdomain, $debug) = @_;
   my ($signer, $key) = get_authinfo($cgi, $host);
 
   my $debugmsg = ($debug) ? "\n" : '';
@@ -269,7 +276,7 @@ sub handle_expire($$$$$) {
       if($rr->type eq 'TXT' &&
 		$rr->txtdata=~/$UpdateTXT(.*\d\d:\d\d:\d\d \d{4})$/){
 	if(my $lastupdate = parse_localtime($1)) {
-	  DNS_Update($dnsdomain, $dnshost, undef, undef, $signer, $key, $debug)
+	  DNS_Update($dnsdomain, $rr->name, undef, undef, $signer, $key, $debug)
 		unless($lastupdate > $validafter);
 	  if($debug) {
 	    $debugmsg .= ($lastupdate > $validafter) ? 'Keeping ' : 'Expiring ';
@@ -286,8 +293,9 @@ sub handle_expire($$$$$) {
   }
 }
 
-sub handle_view($$$$$) {
-  my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_;
+sub handle_view($$$$) {
+  my ($mode, $host, $dnsdomain, $debug) = @_;
+  my $dnshost = expand_CNAME($host);
   my $title = "DynDNS Updater - $host";
   print $cgi->header(-status=>200),
 	$cgi->start_html(-title => $title),
@@ -310,8 +318,8 @@ sub handle_view($$$$$) {
   print $cgi->end_html();
 }
 
-sub handle_list($$$$$) {
-  my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_;
+sub handle_list($$$$) {
+  my ($mode, $host, $dnsdomain, $debug) = @_;
   my $title = "DynDNS Updater - $dnsdomain";
 
   print $cgi->header(-status=>200),
@@ -345,7 +353,8 @@ if ($ConfigFile cmp 'ignore') {
     $CFGFile =~ s/(\.pl)?$/.cfg/;
     if (open (CONFIG, $CFGFile)) {
         my %CONFIG = (
-            allow_debug_key => \$AllowDebugKey, dns_server      => \$DNSServer,
+            allow_debug_key => \$AllowDebugKey,
+            dns_server      => \$DNSServer,     dns_domain      => \@DNSDomain,
             expand_cnames   => \$ExpandCNAMEs,  auth_mode       => \$AuthMode,
             static_signer   => \$StaticSigner,  static_key      => \$StaticKey,
             require_rr      => \$RequireRR,     replace_rr      => \@ReplaceRR,
@@ -399,6 +408,20 @@ foreach my $rrtype (@ReplaceRR) {
 my $mode = $cgi->path_info || $cgi->param('mode') || 'view';
 $mode=~s/^\/([^\/]+)(\/(.*))?/$1/;
 my $host = $cgi->param('host') || $3;
+my $dnsdomain;
+foreach my $d (@DNSDomain) {
+    if ($d eq '!') { $d = $cgi->virtual_host; }
+    elsif ($d eq '?') { $d = $cgi->param('domain'); }
+    elsif ($d =~ /-?\d+/) {
+        if ($d <0) { $d = join('.', splice([ split(/\./, $cgi->virtual_host) ], $d)); }
+        else { $d = join('.', splice([ split(/\./, $host) ], ($d) ? -$d : 1)); }
+    }
+    $dnsdomain = $d if ($host && length($host) == length($d)+rindex($host,$d));
+    last if $dnsdomain;
+}
+fail($PE, "No host name to act on specified", 400)
+        unless $host || $mode eq 'list' || $mode eq 'expire';
+fail($PE, "No host or domain name to act on specified", 400) unless $dnsdomain;
 
 
 ##############################
@@ -410,13 +433,8 @@ my %handlers = (
   list		=> \&handle_list,
   expire	=> \&handle_expire,
 );
-if($host eq '' and $mode cmp 'list' and $mode cmp 'expire') {
-  fail($PE, "No host name to act on specified", 400);
-} elsif(my $handler = $handlers{$mode}) {
-  # Replace provided host with that of a CNAME it points to and determine domain
-  my $dnshost = ($host) ? expand_CNAME($host) : undef;
-  my $dnsdomain = $cgi->param('domain') || ($dnshost=~/\.(.*)$/)[0];
-  $handler->($mode, $host, $dnshost, $dnsdomain, $debug);
+if(my $handler = $handlers{$mode}) {
+  $handler->($mode, $host, $dnsdomain, $debug);
 } else {
   fail("File Not Found", "Invalid Mode '$mode' specified", 404);
 }