Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add some network diagnostics #589

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
80 changes: 80 additions & 0 deletions src/bin/curl.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(* A debug tool, intended to check the I/O subsystem is working correctly. *)

open Lwt.Infix

let lookup host =
Host.Dns.getaddrinfo host `INET
>>= function
| [] ->
Lwt.fail_with (Printf.sprintf "unable to lookup %s" host)
| Ipaddr.V6 _ :: _ ->
Lwt.fail_with "IPv6 not currently supported."
| Ipaddr.V4 ipv4 :: _ ->
Lwt.return (Ipaddr.V4 ipv4)

module Client(FLOW: Mirage_flow.S) = struct
module C = Mirage_channel.Make(FLOW)
let get flow host path =
let request = "GET " ^ path ^ " HTTP/1.0\r\nHost: " ^ host ^ "\r\nConnection: close\r\n\r\n" in
let c = C.create flow in
Printf.printf "writing\n%s\n" request;
C.write_string c request 0 (String.length request);
C.flush c
>>= function
| Error e ->
Printf.printf "error sending request: %s\n" (Fmt.str "%a" C.pp_write_error e);
Lwt.return_unit
| Ok () ->
let rec loop () =
C.read_some c >>= function
| Ok `Eof -> Lwt.return_unit
| Error e ->
Printf.printf "error reading response: %s\n" (Fmt.str "%a" C.pp_error e);
Lwt.return_unit
| Ok (`Data buf) ->
print_string (Cstruct.to_string buf);
loop () in
loop ()
end

let curl _verbose urls =
let module HTTP = Client(Host.Sockets.Stream.Tcp) in
let fetch host port path =
let path = if path = "" then "/" else path in
lookup host
>>= fun ipv4 ->
Printf.printf "connecting to %s:%d\n" (Ipaddr.to_string ipv4) port;
Host.Sockets.Stream.Tcp.connect (ipv4, port)
>>= function
| Error (`Msg m) ->
Printf.printf "unable to connect: %s\n" m;
Lwt.return_unit
| Ok socket ->
Printf.printf "connected\n";
Lwt.finalize
(fun () ->
HTTP.get socket host path
) (fun () -> Host.Sockets.Stream.Tcp.close socket) in
try
Host.Main.run begin
Lwt_list.iter_s (fun url ->
let uri = Uri.of_string url in
if Uri.scheme uri <> Some "http" then begin
Printf.printf "only http:// URLs are currently supported by this debug tool\n";
Lwt.return_unit
end else begin
Printf.printf "trying URL %s\n" url;
let path = Uri.path uri in
match Uri.host uri, Uri.port uri with
| Some host, Some port ->
fetch host port path
| Some host, None ->
fetch host 80 path
| _, _ ->
Printf.printf "unable to parse host and port from URL\n";
Lwt.return_unit
end
) urls
end
with e ->
Printf.printf "Host.Main.run caught exception %s: %s\n" (Printexc.to_string e) (Printexc.get_backtrace ())
35 changes: 30 additions & 5 deletions src/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ let hvsock_addr_of_uri ~default_serviceid uri =
max_connections port_forwards dns http hosts host_names gateway_names
vm_names listen_backlog port_max_idle_time debug
server_macaddr domain allowed_bind_addresses gateway_ip host_ip lowest_ip highest_ip
dhcp_json_path mtu udpv4_forwards tcpv4_forwards gateway_forwards_path gc_compact
dhcp_json_path mtu udpv4_forwards tcpv4_forwards gateway_forwards_path forwards_path gc_compact
=
let level =
let env_debug =
Expand Down Expand Up @@ -543,6 +543,7 @@ let hvsock_addr_of_uri ~default_serviceid uri =
udpv4_forwards;
tcpv4_forwards;
gateway_forwards_path;
forwards_path;
pcap_snaplen;
} in
match socket_url with
Expand Down Expand Up @@ -816,6 +817,14 @@ let gateway_forwards_path =
in
Arg.(value & opt (some string) None doc)

let forwards_path =
let doc =
Arg.info ~doc:
"Path of forwards configuration file"
[ "forwards" ]
in
Arg.(value & opt (some string) None doc)

let gc_compact =
let doc =
Arg.info ~doc:
Expand All @@ -824,7 +833,7 @@ let gc_compact =
in
Arg.(value & opt (some int) None doc)

let command =
let ethernet_cmd =
let doc = "proxy TCP/IP connections from an ethernet link via sockets" in
let man =
[`S "DESCRIPTION";
Expand All @@ -837,8 +846,24 @@ let command =
$ host_names $ gateway_names $ vm_names $ listen_backlog $ port_max_idle_time $ debug
$ server_macaddr $ domain $ allowed_bind_addresses $ gateway_ip $ host_ip
$ lowest_ip $ highest_ip $ dhcp_json_path $ mtu $ udpv4_forwards $ tcpv4_forwards
$ gateway_forwards_path $ gc_compact),
Term.info (Filename.basename Sys.argv.(0)) ~version:Version.git ~doc ~man
$ gateway_forwards_path $ forwards_path $ gc_compact),
Term.info "ethernet" ~version:Version.git ~doc ~man


let verbose =
let doc = "Extra verbose logging"in
Arg.(value & flag & info ["v"; "verbose"] ~doc)

let urls = Arg.(value & pos_all string [] & info [] ~docv:"URL")

let curl_cmd =
let doc = "A debug command which fetches a resource over HTTP" in
let man =
[`S "DESCRIPTION";
`P "Fetch a resource over HTTP to help diagnose local firewall or anti-virus problems."]
in
Term.(const Curl.curl $ verbose $ urls),
Term.info "curl" ~version:Version.git ~doc ~man

let () =
Printexc.record_backtrace true;
Expand All @@ -847,4 +872,4 @@ let () =
Log.err (fun f ->
f "Lwt.async failure %a: %s" Fmt.exn exn (Printexc.get_backtrace ()))
);
Term.exit @@ Term.eval command
Term.exit @@ Term.eval_choice ethernet_cmd [ethernet_cmd; curl_cmd]
2 changes: 1 addition & 1 deletion src/fs9p/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(library
(name fs9p)
(wrapped false)
(libraries protocol-9p mirage-flow))
(libraries protocol-9p mirage-flow result))
5 changes: 4 additions & 1 deletion src/hostnet/configuration.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ type t = {
udpv4_forwards: Gateway_forwards.t;
tcpv4_forwards: Gateway_forwards.t;
gateway_forwards_path: string option;
forwards_path: string option;
pcap_snaplen: int;
}

let to_string t =
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_names = %s; vm_names = %s; udpv4_forwards = %s; tcpv4_forwards = %s; gateway_forwards_path = %s; pcap_snaplen = %d"
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_names = %s; vm_names = %s; udpv4_forwards = %s; tcpv4_forwards = %s; gateway_forwards_path = %s; forwards_path = %s; pcap_snaplen = %d"
(Macaddr.to_string t.server_macaddr)
(match t.max_connections with None -> "None" | Some x -> string_of_int x)
(match t.dns_path with None -> "None" | Some x -> x)
Expand All @@ -85,6 +86,7 @@ let to_string t =
(Gateway_forwards.to_string t.udpv4_forwards)
(Gateway_forwards.to_string t.tcpv4_forwards)
(match t.gateway_forwards_path with None -> "None" | Some x -> x)
(match t.forwards_path with None -> "None" | Some x -> x)
t.pcap_snaplen

let no_dns_servers =
Expand Down Expand Up @@ -132,6 +134,7 @@ let default = {
udpv4_forwards = [];
tcpv4_forwards = [];
gateway_forwards_path = None;
forwards_path = None;
pcap_snaplen = default_pcap_snaplen;
}

Expand Down
Loading