qubes-mirage-firewall/unikernel.ml

79 lines
2.9 KiB
OCaml
Raw Normal View History

2015-12-30 04:52:24 -05:00
(* Copyright (C) 2015, Thomas Leonard <thomas.leonard@unikernel.com>
See the README file for details. *)
open Lwt
open Qubes
let src = Logs.Src.create "unikernel" ~doc:"Main unikernel code"
module Log = (val Logs.src_log src : Logs.LOG)
2015-12-30 08:59:13 -05:00
(* Configure logging *)
2015-12-30 04:52:24 -05:00
let () =
let open Logs in
(* Set default log level *)
set_level (Some Logs.Info)
2015-12-30 04:52:24 -05:00
module Main (Clock : V1.CLOCK) = struct
module Logs_reporter = Mirage_logs.Make(Clock)
2015-12-30 08:59:13 -05:00
module Uplink = Uplink.Make(Clock)
2015-12-30 04:52:24 -05:00
2015-12-30 08:59:13 -05:00
(* Set up networking and listen for incoming packets. *)
let network qubesDB =
(* Read configuration from QubesDB *)
let config = Dao.read_network_config qubesDB in
Logs.info (fun f -> f "Client (internal) network is %a"
Ipaddr.V4.Prefix.pp_hum config.Dao.clients_prefix);
2015-12-30 08:59:13 -05:00
(* Initialise connection to NetVM *)
Uplink.connect config >>= fun uplink ->
(* Report success *)
Dao.set_iptables_error qubesDB "" >>= fun () ->
(* Set up client-side networking *)
let client_eth = Client_eth.create
~client_gw:config.Dao.clients_our_ip
~prefix:config.Dao.clients_prefix in
(* Set up routing between networks and hosts *)
let router = Router.create
~client_eth
~uplink:(Uplink.interface uplink) in
2015-12-30 08:59:13 -05:00
(* Handle packets from both networks *)
Lwt.join [
Client_net.listen router;
Uplink.listen uplink router
]
(* Control which of the messages that reach the reporter are logged to the console.
The rest will be displayed only if an error occurs.
Note: use the regular [Logs] configuration settings to determine which messages
reach the reporter in the first place. *)
let console_threshold _ = Logs.Info
2015-12-30 08:59:13 -05:00
(* Main unikernel entry point (called from auto-generated main.ml). *)
2015-12-30 04:52:24 -05:00
let start () =
let start_time = Clock.time () in
Logs_reporter.(create ~ring_size:20 ~console_threshold () |> run) @@ fun () ->
2015-12-30 04:52:24 -05:00
(* Start qrexec agent, GUI agent and QubesDB agent in parallel *)
let qrexec = RExec.connect ~domid:0 () in
let gui = GUI.connect ~domid:0 () in
let qubesDB = DB.connect ~domid:0 () in
(* Wait for clients to connect *)
qrexec >>= fun qrexec ->
let agent_listener = RExec.listen qrexec Command.handler in
gui >>= fun gui ->
Lwt.async (fun () -> GUI.listen gui);
qubesDB >>= fun qubesDB ->
Log.info (fun f -> f "agents connected in %.3f s (CPU time used since boot: %.3f s)"
(Clock.time () -. start_time) (Sys.time ()));
2015-12-30 04:52:24 -05:00
(* Watch for shutdown requests from Qubes *)
let shutdown_rq =
OS.Lifecycle.await_shutdown_request () >>= fun (`Poweroff | `Reboot) ->
return () in
2015-12-30 04:52:24 -05:00
(* Set up networking *)
2015-12-30 08:59:13 -05:00
let net_listener = network qubesDB in
2016-01-02 10:59:59 -05:00
(* Report memory usage to XenStore *)
Memory_pressure.init ();
2015-12-30 04:52:24 -05:00
(* Run until something fails or we get a shutdown request. *)
2015-12-30 08:59:13 -05:00
Lwt.choose [agent_listener; net_listener; shutdown_rq] >>= fun () ->
2015-12-30 04:52:24 -05:00
(* Give the console daemon time to show any final log messages. *)
OS.Time.sleep 1.0
end