Skip to content

Commit 3e501e9

Browse files
committed
Recursively resolve CNAMES
Previously we used the blocking `Dnssd.query` function which did this for us; now that we've switched to an asynchronous style we must do this ourselves here. Signed-off-by: David Scott <[email protected]>
1 parent 9c725e7 commit 3e501e9

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

Diff for: src/hostnet/host.ml

+31-1
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ module Dns = struct
11331133

11341134
let resolve_dnssd question =
11351135
let open Dns.Packet in
1136-
let query name ty =
1136+
let query_one name ty =
11371137
let query = Dnssd.LowLevel.query (Dns.Name.to_string name) ty in
11381138
let socket = Dnssd.LowLevel.socket query in
11391139
let t, u = Lwt.task () in
@@ -1164,6 +1164,36 @@ module Dns = struct
11641164
) ()
11651165
end in
11661166

1167+
let query requested_name ty =
1168+
(* The DNSServiceRef API will return CNAMEs first, without resolving to
1169+
A/AAAA/... This function recursively resolves the CNAMES while avoiding
1170+
returning duplicate records. *)
1171+
(* NB we only return NoSuchRecord if we find no records. This is because it
1172+
is possible to query a CNAME which exists, but which points to a non-existent
1173+
record. *)
1174+
let open Dnssd in
1175+
let rec loop acc name ty =
1176+
query_one name ty
1177+
>>= function
1178+
(* When we're recursing, ignore the NoSuchRecord error *)
1179+
| Error NoSuchRecord when name <> requested_name -> Lwt.return (Ok acc)
1180+
| Error e -> Lwt.return (Error e)
1181+
| Ok rrs ->
1182+
let not_seen_before = List.filter (fun x -> not (List.mem x acc)) rrs in
1183+
(* If there are any CNAMEs, resolve these too *)
1184+
let cnames = List.rev @@ List.fold_left (fun acc rr ->
1185+
match rr.Dns.Packet.rdata with
1186+
| CNAME name -> name :: acc
1187+
| _ -> acc
1188+
) [] not_seen_before in
1189+
Lwt_list.fold_left_s
1190+
(fun acc name -> match acc with
1191+
| Error e -> Lwt.return (Error e)
1192+
| Ok acc ->
1193+
loop acc name ty
1194+
) (Ok (acc @ not_seen_before)) cnames in
1195+
loop [] requested_name ty in
1196+
11671197
begin match question with
11681198
| { q_class = Q_IN; q_name; _ } when q_name = localhost_local ->
11691199
Log.debug (fun f -> f "DNS lookup of localhost.local: return NXDomain");

0 commit comments

Comments
 (0)