about summary refs log tree commit diff stats
path: root/modules/by-name/dn/dns
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-03-04 19:23:44 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-03-09 13:44:25 +0100
commit8afe668cd69f3aa5b61583b09ebeef67cbafc543 (patch)
treedd1b861ba1381f90fcf9970ca552269b311645ee /modules/by-name/dn/dns
parentpkgs/stalwart-mail-free: Also patch to use the platform CA store (diff)
downloadnixos-server-8afe668cd69f3aa5b61583b09ebeef67cbafc543.zip
modules/dns/dns/types/records/PTR.nix: Special case for reverse IP lookups
This makes implementing a DNS server in tests easier.
Diffstat (limited to 'modules/by-name/dn/dns')
-rw-r--r--modules/by-name/dn/dns/dns/types/records/PTR.nix78
1 files changed, 73 insertions, 5 deletions
diff --git a/modules/by-name/dn/dns/dns/types/records/PTR.nix b/modules/by-name/dn/dns/dns/types/records/PTR.nix
index 32a1913..075f82e 100644
--- a/modules/by-name/dn/dns/dns/types/records/PTR.nix
+++ b/modules/by-name/dn/dns/dns/types/records/PTR.nix
@@ -10,15 +10,83 @@
   ...
 }: let
   inherit (lib) mkOption;
+
+  inherit (lib.strings) stringToCharacters splitString;
+
+  reverseIpv4 = input:
+    builtins.concatStringsSep "." (lib.lists.reverseList (splitString "."
+        input));
+
+  reverseIpv6 = input: let
+    split = splitString ":" input;
+    elementLength = builtins.length split;
+
+    reverseString = string:
+      builtins.concatStringsSep "" (lib.lists.reverseList
+        (stringToCharacters string));
+  in
+    reverseString (builtins.concatStringsSep "." (stringToCharacters (builtins.concatStringsSep
+      "" (builtins.map (
+          part: let
+            c = stringToCharacters part;
+          in
+            if builtins.length c == 4
+            then
+              # valid part
+              part
+            else if builtins.length c < 4 && builtins.length c > 0
+            then
+              # leading zeros were elided
+              (builtins.concatStringsSep "" (
+                builtins.map builtins.toString (
+                  builtins.genList (_: 0) (4 - (builtins.length c))
+                )
+              ))
+              + part
+            else if builtins.length c == 0
+            then
+              # Multiple full blocks were elided. Only one of these can be in an
+              # IPv6 address, as such we can simply add (8 - (elementLength - 1)) `0000`
+              # blocks. We need to substract one from `elementLength` because
+              # this empty part is included in the `elementLength`.
+              builtins.concatStringsSep "" (builtins.genList (_: "0000") (8 - (elementLength - 1)))
+            else builtins.throw "Impossible"
+        )
+        split))));
 in {
   rtype = "PTR";
   options = {
-    ptrdname = mkOption {
+    name = mkOption {
       type = simple.types.domain-name;
-      example = "4-3-2-1.dynamic.example.com.";
-      description = "A <domain-name> which points to some location in the domain name space";
+      example = "mail2.server.com";
+      description = "The <domain-name> which is defined by the IP.";
+    };
+    ip = {
+      v4 = mkOption {
+        type = lib.types.nullOr lib.types.str;
+        example = "192.168.1.4";
+        description = "The IPv4 address of the host.";
+        default = null;
+        apply = v:
+          if v != null
+          then reverseIpv4 v
+          else v;
+      };
+      v6 = mkOption {
+        type = lib.types.nullOr lib.types.str;
+        example = "192.168.1.4";
+        description = "The IPv6 address of the host.";
+        default = null;
+        apply = v:
+          if v != null
+          then reverseIpv6 v
+          else v;
+      };
     };
   };
-  dataToString = {ptrdname, ...}: "${ptrdname}";
-  fromString = ptrdname: {inherit ptrdname;};
+  dataToString = {name, ...}: "${name}.";
+  nameFixup = name: self:
+    if self.ip.v6 == null
+    then "${self.ip.v4}.in-addr.arpa"
+    else "${self.ip.v6}.ip6.arpa";
 }