mirror of
https://github.com/mirage/qubes-mirage-firewall.git
synced 2024-10-01 01:05:39 -04:00
use a fresh client for requesting vif and ip
in the callback to "Xs_client.wait", all operations are tracked and new watches are installed (that are never removed, due to xenstore's xs_handle "accessed_path" never removes any elements of the "accessed_paths" (a mutable StringSet). So, whatever is done in the callback of wait needs to take care (if returning EAGAIN and thus forcing xenstore to continue waiting/watching) that accesses are tracked. Our way out is to create a fresh client and read the IP address with that new client -> the watcher isn't extended -> no dangling (leaking) watches, and no leaking only-expanding StringSet.
This commit is contained in:
parent
0e0917f4fe
commit
d094b20950
70
dao.ml
70
dao.ml
@ -65,43 +65,44 @@ let read_rules rules client_ip =
|
|||||||
icmp_type = None;
|
icmp_type = None;
|
||||||
number = 0;})]
|
number = 0;})]
|
||||||
|
|
||||||
let vifs ~handle domid =
|
let vifs client domid =
|
||||||
match String.to_int domid with
|
match String.to_int domid with
|
||||||
| None -> Log.err (fun f -> f "Invalid domid %S" domid); Lwt.return []
|
| None -> Log.err (fun f -> f "Invalid domid %S" domid); Lwt.return []
|
||||||
| Some domid ->
|
| Some domid ->
|
||||||
let path = Printf.sprintf "backend/vif/%d" domid in
|
let path = Printf.sprintf "backend/vif/%d" domid in
|
||||||
directory ~handle path >>=
|
Xen_os.Xs.immediate client (fun handle ->
|
||||||
Lwt_list.filter_map_p (fun device_id ->
|
directory ~handle path >>=
|
||||||
match String.to_int device_id with
|
Lwt_list.filter_map_p (fun device_id ->
|
||||||
| None -> Log.err (fun f -> f "Invalid device ID %S for domid %d" device_id domid); Lwt.return_none
|
match String.to_int device_id with
|
||||||
| Some device_id ->
|
| None -> Log.err (fun f -> f "Invalid device ID %S for domid %d" device_id domid); Lwt.return_none
|
||||||
let vif = { ClientVif.domid; device_id } in
|
| Some device_id ->
|
||||||
Lwt.try_bind
|
let vif = { ClientVif.domid; device_id } in
|
||||||
(fun () -> Xen_os.Xs.read handle (Printf.sprintf "%s/%d/ip" path device_id))
|
Lwt.try_bind
|
||||||
(fun client_ip ->
|
(fun () -> Xen_os.Xs.read handle (Printf.sprintf "%s/%d/ip" path device_id))
|
||||||
let client_ip' = match String.cuts ~sep:" " client_ip with
|
(fun client_ip ->
|
||||||
| [] -> Log.err (fun m -> m "unexpected empty list"); ""
|
let client_ip' = match String.cuts ~sep:" " client_ip with
|
||||||
| [ ip ] -> ip
|
| [] -> Log.err (fun m -> m "unexpected empty list"); ""
|
||||||
| ip::rest ->
|
| [ ip ] -> ip
|
||||||
Log.warn (fun m -> m "ignoring IPs %s from %a, we support one IP per client"
|
| ip::rest ->
|
||||||
(String.concat ~sep:" " rest) ClientVif.pp vif);
|
Log.warn (fun m -> m "ignoring IPs %s from %a, we support one IP per client"
|
||||||
ip
|
(String.concat ~sep:" " rest) ClientVif.pp vif);
|
||||||
in
|
ip
|
||||||
match Ipaddr.V4.of_string client_ip' with
|
in
|
||||||
| Ok ip -> Lwt.return (Some (vif, ip))
|
match Ipaddr.V4.of_string client_ip' with
|
||||||
| Error `Msg msg ->
|
| Ok ip -> Lwt.return (Some (vif, ip))
|
||||||
Log.err (fun f -> f "Error parsing IP address of %a from %s: %s"
|
| Error `Msg msg ->
|
||||||
ClientVif.pp vif client_ip msg);
|
Log.err (fun f -> f "Error parsing IP address of %a from %s: %s"
|
||||||
Lwt.return None
|
ClientVif.pp vif client_ip msg);
|
||||||
)
|
Lwt.return None
|
||||||
(function
|
)
|
||||||
| Xs_protocol.Enoent _ -> Lwt.return None
|
(function
|
||||||
| ex ->
|
| Xs_protocol.Enoent _ -> Lwt.return None
|
||||||
Log.err (fun f -> f "Error getting IP address of %a: %s"
|
| ex ->
|
||||||
ClientVif.pp vif (Printexc.to_string ex));
|
Log.err (fun f -> f "Error getting IP address of %a: %s"
|
||||||
Lwt.return None
|
ClientVif.pp vif (Printexc.to_string ex));
|
||||||
)
|
Lwt.return None
|
||||||
)
|
)
|
||||||
|
))
|
||||||
|
|
||||||
let watch_clients fn =
|
let watch_clients fn =
|
||||||
Xen_os.Xs.make () >>= fun xs ->
|
Xen_os.Xs.make () >>= fun xs ->
|
||||||
@ -114,7 +115,8 @@ let watch_clients fn =
|
|||||||
| Xs_protocol.Enoent _ -> Lwt.return []
|
| Xs_protocol.Enoent _ -> Lwt.return []
|
||||||
| ex -> Lwt.fail ex)
|
| ex -> Lwt.fail ex)
|
||||||
end >>= fun items ->
|
end >>= fun items ->
|
||||||
Lwt_list.map_p (vifs ~handle) items >>= fun items ->
|
Xen_os.Xs.make () >>= fun xs ->
|
||||||
|
Lwt_list.map_p (vifs xs) items >>= fun items ->
|
||||||
fn (List.concat items |> VifMap.of_list);
|
fn (List.concat items |> VifMap.of_list);
|
||||||
(* Wait for further updates *)
|
(* Wait for further updates *)
|
||||||
Lwt.fail Xs_protocol.Eagain
|
Lwt.fail Xs_protocol.Eagain
|
||||||
|
Loading…
Reference in New Issue
Block a user