Skip to content

Commit eb5c995

Browse files
committed
Add command-line argument --gateway-names
We now have - `--host-names`: DNS names for the localhost proxied services - `--gateway-names`: DNS names for the gateway IP (where DNS, NTP, HTTP proxies are running) Signed-off-by: David Scott <[email protected]>
1 parent bf0a28d commit eb5c995

File tree

7 files changed

+67
-33
lines changed

7 files changed

+67
-33
lines changed

src/bin/main.ml

+14-3
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ let hvsock_addr_of_uri ~default_serviceid uri =
339339

340340
let main
341341
socket_url port_control_url introspection_url diagnostics_url
342-
max_connections vsock_path db_path db_branch dns http hosts host_names
342+
max_connections vsock_path db_path db_branch dns http hosts host_names gateway_names
343343
listen_backlog port_max_idle_time debug
344344
server_macaddr domain allowed_bind_addresses gateway_ip host_ip lowest_ip highest_ip
345345
dhcp_json_path mtu log_destination
@@ -358,6 +358,8 @@ let hvsock_addr_of_uri ~default_serviceid uri =
358358
end;
359359

360360
let host_names = List.map Dns.Name.of_string @@ Astring.String.cuts ~sep:"," host_names in
361+
let gateway_names = List.map Dns.Name.of_string @@ Astring.String.cuts ~sep:"," gateway_names in
362+
361363
let dns_path, resolver = match dns with
362364
| None -> None, Configuration.default_resolver
363365
| Some file -> Some file, `Upstream in
@@ -372,6 +374,7 @@ let hvsock_addr_of_uri ~default_serviceid uri =
372374
max_connections;
373375
port_max_idle_time;
374376
host_names;
377+
gateway_names;
375378
dns = Configuration.no_dns_servers;
376379
dns_path;
377380
http_intercept_path = http;
@@ -528,7 +531,15 @@ let host_names =
528531
"Comma-separated list of DNS names to map to the Host's virtual IP"
529532
["host-names"]
530533
in
531-
Arg.(value & opt string "vpnkit.host" doc)
534+
Arg.(value & opt string "host.internal" doc)
535+
536+
let gateway_names =
537+
let doc =
538+
Arg.info ~doc:
539+
"Comma-separated list of DNS names to map to the gateway's virtual IP"
540+
["gateway-names"]
541+
in
542+
Arg.(value & opt string "gateway.internal" doc)
532543

533544
let listen_backlog =
534545
let doc = "Specify a maximum listen(2) backlog. If no override is specified \
@@ -619,7 +630,7 @@ let command =
619630
Term.(pure main
620631
$ socket $ port_control_path $ introspection_path $ diagnostics_path
621632
$ max_connections $ vsock_path $ db_path $ db_branch $ dns $ http $ hosts
622-
$ host_names $ listen_backlog $ port_max_idle_time $ debug
633+
$ host_names $ gateway_names $ listen_backlog $ port_max_idle_time $ debug
623634
$ server_macaddr $ domain $ allowed_bind_addresses $ gateway_ip $ host_ip
624635
$ lowest_ip $ highest_ip $ dhcp_json_path $ mtu $ Logging.log_destination),
625636
Term.info (Filename.basename Sys.argv.(0)) ~version:"%%VERSION%%" ~doc ~man

src/hostnet/configuration.ml

+6-1
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ type t = {
5252
http_intercept_path: string option;
5353
port_max_idle_time: int;
5454
host_names: Dns.Name.t list;
55+
gateway_names: Dns.Name.t list;
5556
}
5657

5758
let to_string t =
58-
Printf.sprintf "server_macaddr = %s; max_connection = %s; dns_path = %s; dns = %s; resolver = %s; domain = %s; allowed_bind_addresses = %s; gateway_ip = %s; host_ip = %s; lowest_ip = %s; highest_ip = %s; dhcp_json_path = %s; dhcp_configuration = %s; mtu = %d; http_intercept = %s; http_intercept_path = %s; port_max_idle_time = %s; host_names = %s"
59+
Printf.sprintf "server_macaddr = %s; max_connection = %s; dns_path = %s; dns = %s; resolver = %s; domain = %s; allowed_bind_addresses = %s; gateway_ip = %s; host_ip = %s; lowest_ip = %s; highest_ip = %s; dhcp_json_path = %s; dhcp_configuration = %s; mtu = %d; http_intercept = %s; http_intercept_path = %s; port_max_idle_time = %s; host_names = %s; gateway_name = %s"
5960
(Macaddr.to_string t.server_macaddr)
6061
(match t.max_connections with None -> "None" | Some x -> string_of_int x)
6162
(match t.dns_path with None -> "None" | Some x -> x)
@@ -74,6 +75,7 @@ let to_string t =
7475
(match t.http_intercept_path with None -> "None" | Some x -> x)
7576
(string_of_int t.port_max_idle_time)
7677
(String.concat ", " (List.map Dns.Name.to_string t.host_names))
78+
(String.concat ", " (List.map Dns.Name.to_string t.gateway_names))
7779

7880
let no_dns_servers =
7981
Dns_forward.Config.({ servers = Server.Set.empty; search = []; assume_offline_after_drops = None })
@@ -90,6 +92,8 @@ let default_port_max_idle_time = 300
9092
(* random MAC from https://www.hellion.org.uk/cgi-bin/randmac.pl *)
9193
let default_server_macaddr = Macaddr.of_string_exn "F6:16:36:BC:F9:C6"
9294
let default_host_names = [ Dns.Name.of_string "vpnkit.host" ]
95+
let default_gateway_names = [ Dns.Name.of_string "gateway.internal" ]
96+
9397
let default_resolver = `Host
9498

9599
let default = {
@@ -111,6 +115,7 @@ let default = {
111115
http_intercept_path = None;
112116
port_max_idle_time = default_port_max_idle_time;
113117
host_names = default_host_names;
118+
gateway_names = default_gateway_names;
114119
}
115120

116121
module Parse = struct

src/hostnet/hostnet_dns.ml

+33-18
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,31 @@ let try_etc_hosts =
135135
end
136136
| _ -> None
137137

138-
let try_builtins local_ip host_names question =
138+
let try_builtins builtin_names question =
139139
let open Dns.Packet in
140-
match local_ip, question with
141-
| Ipaddr.V4 local_ip, { q_class = Q_IN; q_type = (Q_A|Q_AAAA); q_name; _ }
142-
when List.mem q_name host_names ->
143-
Log.info (fun f ->
144-
f "DNS: %s is a builtin: %a" (Dns.Name.to_string q_name)
145-
Ipaddr.V4.pp_hum local_ip);
146-
Some [ { name = q_name; cls = RR_IN; flush = false; ttl = 0l;
147-
rdata = A local_ip } ]
140+
match question with
141+
| { q_class = Q_IN; q_type = (Q_A|Q_AAAA); q_name; _ } ->
142+
let bindings = List.filter (fun (name, _) -> name = q_name) builtin_names in
143+
let ipv4_rrs =
144+
List.fold_left (fun acc (_, ip) ->
145+
match ip with
146+
| Ipaddr.V4 ipv4 -> { name = q_name; cls = RR_IN; flush = false; ttl = 0l; rdata = A ipv4 } :: acc
147+
| _ -> acc
148+
) [] bindings in
149+
let ipv6_rrs =
150+
List.fold_left (fun acc (_, ip) ->
151+
match ip with
152+
| Ipaddr.V6 ipv6 -> { name = q_name; cls = RR_IN; flush = false; ttl = 0l; rdata = AAAA ipv6 } :: acc
153+
| _ -> acc
154+
) [] bindings in
155+
let rrs = if question.q_type = Q_A then ipv4_rrs else ipv6_rrs in
156+
if rrs = [] then None else begin
157+
Log.info (fun f ->
158+
f "DNS: %s is a builtin: %s" (Dns.Name.to_string q_name)
159+
(String.concat "; " (List.map (fun rr -> Dns.Packet.rr_to_string rr) rrs))
160+
);
161+
Some rrs
162+
end
148163
| _ -> None
149164

150165
module Make
@@ -191,7 +206,7 @@ struct
191206

192207
type t = {
193208
local_ip: Ipaddr.t;
194-
host_names: Dns.Name.t list;
209+
builtin_names: (Dns.Name.t * Ipaddr.t) list;
195210
resolver: resolver;
196211
}
197212

@@ -271,13 +286,13 @@ struct
271286
| None ->
272287
Random.int bound
273288

274-
let create ~local_address ~host_names =
289+
let create ~local_address ~builtin_names =
275290
let local_ip = local_address.Dns_forward.Config.Address.ip in
276291
Log.info (fun f ->
277-
let prefix = match host_names with
278-
| [] -> "No DNS names"
279-
| _ -> Printf.sprintf "DNS names [ %s ]" (String.concat ", " @@ List.map Dns.Name.to_string host_names) in
280-
f "%s will map to local IP %s" prefix (Ipaddr.to_string local_ip));
292+
let suffix = match builtin_names with
293+
| [] -> "no builtin DNS names; everything will be forwarded"
294+
| _ -> Printf.sprintf "builtin DNS names [ %s ]" (String.concat ", " @@ List.map (fun (name, ip) -> Dns.Name.to_string name ^ " -> " ^ (Ipaddr.to_string ip)) builtin_names) in
295+
f "DNS server configured with %s" suffix);
281296
fun clock -> function
282297
| `Upstream config ->
283298
let open Dns_forward.Config.Address in
@@ -300,11 +315,11 @@ struct
300315
>>= fun dns_udp_resolver ->
301316
Dns_tcp_resolver.create ~gen_transaction_id ~message_cb config clock
302317
>>= fun dns_tcp_resolver ->
303-
Lwt.return { local_ip; host_names;
318+
Lwt.return { local_ip; builtin_names;
304319
resolver = Upstream { dns_tcp_resolver; dns_udp_resolver } }
305320
| `Host ->
306321
Log.info (fun f -> f "Will use the host's DNS resolver");
307-
Lwt.return { local_ip; host_names; resolver = Host }
322+
Lwt.return { local_ip; builtin_names; resolver = Host }
308323

309324
let answer t is_tcp buf =
310325
let open Dns.Packet in
@@ -327,7 +342,7 @@ struct
327342
| Some answers ->
328343
Lwt.return (Ok (marshal @@ reply answers))
329344
| None ->
330-
match try_builtins t.local_ip t.host_names question with
345+
match try_builtins t.builtin_names question with
331346
| Some answers ->
332347
Lwt.return (Ok (marshal @@ reply answers))
333348
| None ->

src/hostnet/hostnet_dns.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ sig
2626

2727
val create:
2828
local_address:Dns_forward.Config.Address.t ->
29-
host_names:Dns.Name.t list ->
29+
builtin_names:(Dns.Name.t * Ipaddr.t) list ->
3030
Clock.t -> Config.t -> t Lwt.t
3131
(** Create a DNS forwarding instance based on the given
3232
configuration, either [`Upstream config]: send DNS requests to

src/hostnet/slirp.ml

+9-6
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,16 @@ struct
109109
module Udp_nat = Hostnet_udp.Make(Host.Sockets)(Clock)(Host.Time)
110110
module Icmp_nat = Hostnet_icmp.Make(Host.Sockets)(Clock)(Host.Time)
111111

112-
let dns_forwarder ~local_address ~host_names clock =
113-
Dns_forwarder.create ~local_address ~host_names clock (Dns_policy.config ())
112+
let dns_forwarder ~local_address ~builtin_names clock =
113+
Dns_forwarder.create ~local_address ~builtin_names clock (Dns_policy.config ())
114114

115115
(* Global variable containing the global DNS configuration *)
116116
let dns =
117117
let ip = Ipaddr.V4 Configuration.default_gateway_ip in
118118
let local_address = { Dns_forward.Config.Address.ip; port = 0 } in
119119
ref (
120120
Clock.connect () >>= fun clock ->
121-
dns_forwarder ~local_address ~host_names:[] clock
121+
dns_forwarder ~local_address ~builtin_names:[] clock
122122
)
123123

124124
(* Global variable containing the global HTTP proxy configuration *)
@@ -837,12 +837,12 @@ struct
837837
let get_nat_table_size t = Udp_nat.get_nat_table_size t.udp_nat
838838

839839
let update_dns
840-
?(local_ip = Ipaddr.V4 Ipaddr.V4.localhost) ?(host_names = []) clock
840+
?(local_ip = Ipaddr.V4 Ipaddr.V4.localhost) ?(builtin_names = []) clock
841841
=
842842
let local_address =
843843
{ Dns_forward.Config.Address.ip = local_ip; port = 0 }
844844
in
845-
dns := dns_forwarder ~local_address ~host_names clock
845+
dns := dns_forwarder ~local_address ~builtin_names clock
846846

847847
let update_http ?http:http_config ?https ?exclude () =
848848
Http_forwarder.create ?http:http_config ?https ?exclude ()
@@ -1176,7 +1176,10 @@ struct
11761176
let local_address =
11771177
{ Dns_forward.Config.Address.ip = Ipaddr.V4 local_ip; port = 0 }
11781178
in
1179-
dns := dns_forwarder ~local_address ~host_names:c.Configuration.host_names clock
1179+
let builtin_names =
1180+
(List.map (fun name -> name, Ipaddr.V4 c.Configuration.gateway_ip) c.Configuration.gateway_names)
1181+
@ (List.map (fun name -> name, Ipaddr.V4 c.Configuration.host_ip) c.Configuration.host_names) in
1182+
dns := dns_forwarder ~local_address ~builtin_names clock
11801183

11811184
let update_dhcp c =
11821185
Log.info (fun f ->

src/hostnet/slirp.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ sig
4646
val get_nat_table_size: connection -> int
4747
(** Return the number of active NAT table entries *)
4848

49-
val update_dns: ?local_ip:Ipaddr.t -> ?host_names:Dns.Name.t list ->
49+
val update_dns: ?local_ip:Ipaddr.t -> ?builtin_names:(Dns.Name.t * Ipaddr.t) list ->
5050
Clock.t -> unit
5151
(** Update the DNS forwarder following a configuration change *)
5252

src/hostnet_test/suite.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ let test_dhcp_query () =
2828
in
2929
run ~pcap:"test_dhcp_query.pcap" t
3030

31-
let set_dns_policy ?host_names use_host =
31+
let set_dns_policy ?builtin_names use_host =
3232
Mclock.connect () >|= fun clock ->
3333
Dns_policy.remove ~priority:3;
3434
Dns_policy.add ~priority:3
3535
~config:(if use_host then `Host else Dns_policy.google_dns);
36-
Slirp_stack.Debug.update_dns ?host_names clock
36+
Slirp_stack.Debug.update_dns ?builtin_names clock
3737

3838
let test_dns_query server use_host () =
3939
let t _ stack =
@@ -51,7 +51,7 @@ let test_dns_query server use_host () =
5151
let test_builtin_dns_query server use_host () =
5252
let name = "experimental.host.name.localhost" in
5353
let t _ stack =
54-
set_dns_policy ~host_names:[ Dns.Name.of_string name ] use_host
54+
set_dns_policy ~builtin_names:[ Dns.Name.of_string name, Ipaddr.V4 (Ipaddr.V4.localhost) ] use_host
5555
>>= fun () ->
5656
let resolver = DNS.create stack.Client.t in
5757
DNS.gethostbyname ~server resolver name >>= function

0 commit comments

Comments
 (0)