Skip to content

Commit 47a530f

Browse files
authored
Merge pull request #272 from djs55/port-timeout
Allow switch port timeout to be configured
2 parents 3dd816d + 633166e commit 47a530f

File tree

5 files changed

+51
-31
lines changed

5 files changed

+51
-31
lines changed

src/bin/main.ml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ let hvsock_addr_of_uri ~default_serviceid uri =
194194
let main_t
195195
socket_url port_control_url introspection_url diagnostics_url
196196
max_connections vsock_path db_path db_branch dns hosts host_names
197-
listen_backlog debug
197+
listen_backlog port_max_idle_time debug
198198
=
199199
(* Write to stdout if expicitly requested [debug = true] or if the
200200
environment variable DEBUG is set *)
@@ -304,7 +304,8 @@ let hvsock_addr_of_uri ~default_serviceid uri =
304304
vnet_switch;
305305
mtu = 1500;
306306
host_names;
307-
clock }
307+
clock;
308+
port_max_idle_time }
308309
in
309310

310311
let config = match db_path with
@@ -374,12 +375,12 @@ let hvsock_addr_of_uri ~default_serviceid uri =
374375
let main
375376
socket_url port_control_url introspection_url diagnostics_url
376377
max_connections vsock_path db_path db_branch dns hosts host_names
377-
listen_backlog debug
378+
listen_backlog port_max_idle_time debug
378379
=
379380
Host.Main.run
380381
(main_t socket_url port_control_url introspection_url diagnostics_url
381382
max_connections vsock_path db_path db_branch dns hosts host_names
382-
listen_backlog debug)
383+
listen_backlog port_max_idle_time debug)
383384

384385
open Cmdliner
385386

@@ -501,6 +502,10 @@ let listen_backlog =
501502
then we will use SOMAXCONN." in
502503
Arg.(value & opt (some int) None & info [ "listen-backlog" ] ~doc)
503504

505+
let port_max_idle_time =
506+
let doc = "Idle time to wait before timing out and disconnecting switch ports." in
507+
Arg.(value & opt int 30 & info [ "port-max-idle-time" ] ~doc)
508+
504509
let debug =
505510
let doc = "Verbose debug logging to stdout" in
506511
Arg.(value & flag & info [ "debug" ] ~doc)
@@ -515,7 +520,7 @@ let command =
515520
Term.(pure main
516521
$ socket $ port_control_path $ introspection_path $ diagnostics_path
517522
$ max_connections $ vsock_path $ db_path $ db_branch $ dns $ hosts
518-
$ host_names $ listen_backlog $ debug),
523+
$ host_names $ listen_backlog $ port_max_idle_time $ debug),
519524
Term.info (Filename.basename Sys.argv.(0)) ~version:Depends.version ~doc ~man
520525

521526
let () =

src/hostnet/slirp.ml

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ type ('a, 'b) config = {
8686
mtu: int;
8787
host_names: Dns.Name.t list;
8888
clock: 'a;
89+
port_max_idle_time: int;
8990
}
9091

9192
module Make
@@ -794,30 +795,34 @@ struct
794795
Lwt.return (Ok ())
795796
end
796797

797-
(* If no traffic is received for 5 minutes, delete the endpoint and
798+
(* If no traffic is received for `port_max_idle_time`, delete the endpoint and
798799
the switch port. *)
799-
let rec delete_unused_endpoints t () =
800-
Host.Time.sleep_ns (Duration.of_sec 30)
801-
>>= fun () ->
802-
Lwt_mutex.with_lock t.endpoints_m
803-
(fun () ->
804-
let now = Unix.gettimeofday () in
805-
let old_ips = IPMap.fold (fun ip endpoint acc ->
806-
let age = now -. endpoint.Endpoint.last_active_time in
807-
if age > 300.0 then ip :: acc else acc
808-
) t.endpoints [] in
809-
List.iter (fun ip ->
810-
Switch.remove t.switch ip;
811-
t.endpoints <- IPMap.remove ip t.endpoints
812-
) old_ips;
813-
Lwt.return_unit
814-
)
815-
>>= fun () ->
816-
delete_unused_endpoints t ()
800+
let rec delete_unused_endpoints t ~port_max_idle_time () =
801+
if port_max_idle_time <= 0
802+
then Lwt.return_unit (* never delete a port *)
803+
else begin
804+
Host.Time.sleep_ns (Duration.of_sec 30)
805+
>>= fun () ->
806+
Lwt_mutex.with_lock t.endpoints_m
807+
(fun () ->
808+
let now = Unix.gettimeofday () in
809+
let old_ips = IPMap.fold (fun ip endpoint acc ->
810+
let age = now -. endpoint.Endpoint.last_active_time in
811+
if age > (float_of_int port_max_idle_time) then ip :: acc else acc
812+
) t.endpoints [] in
813+
List.iter (fun ip ->
814+
Switch.remove t.switch ip;
815+
t.endpoints <- IPMap.remove ip t.endpoints
816+
) old_ips;
817+
Lwt.return_unit
818+
)
819+
>>= fun () ->
820+
delete_unused_endpoints t ~port_max_idle_time ()
821+
end
817822

818823
let connect x vnet_switch vnet_client_id client_macaddr server_macaddr peer_ip
819824
local_ip highest_ip extra_dns_ip mtu get_domain_search get_domain_name
820-
(global_arp_table:arp_table) clock
825+
(global_arp_table:arp_table) clock port_max_idle_time
821826
=
822827

823828
let valid_subnets = [ Ipaddr.V4.Prefix.global ] in
@@ -871,7 +876,7 @@ struct
871876
udp_nat;
872877
icmp_nat;
873878
} in
874-
Lwt.async @@ delete_unused_endpoints t;
879+
Lwt.async @@ delete_unused_endpoints ~port_max_idle_time t;
875880

876881
let find_endpoint ip =
877882
Lwt_mutex.with_lock t.endpoints_m
@@ -1342,11 +1347,16 @@ struct
13421347
log_exception_continue "monitor http interception settings" (fun () ->
13431348
monitor_http_intercept_settings http_intercept_settings));
13441349

1350+
let port_max_idle_time_path = driver @ [ "slirp"; "port-max-idle-time" ] in
1351+
Config.int config ~default:300 port_max_idle_time_path
1352+
>>= fun port_max_idle_times ->
1353+
let port_max_idle_time = Active_config.hd port_max_idle_times in
1354+
13451355
Log.info (fun f ->
13461356
f "Creating slirp server peer_ip:%s local_ip:%s domain_search:%s \
1347-
mtu:%d"
1357+
mtu:%d port_max_idle_time:%d"
13481358
(Ipaddr.V4.to_string peer_ip) (Ipaddr.V4.to_string local_ip)
1349-
(String.concat " " !domain_search) mtu
1359+
(String.concat " " !domain_search) mtu port_max_idle_time
13501360
);
13511361

13521362
let global_arp_table : arp_table = {
@@ -1371,6 +1381,7 @@ struct
13711381
mtu;
13721382
host_names;
13731383
clock;
1384+
port_max_idle_time;
13741385
} in
13751386
Lwt.return t
13761387

@@ -1484,7 +1495,7 @@ struct
14841495
connect x t.vnet_switch vnet_client_id client_macaddr t.server_macaddr
14851496
client_ip t.local_ip t.highest_ip t.extra_dns_ip t.mtu
14861497
t.get_domain_search t.get_domain_name t.global_arp_table
1487-
t.clock
1498+
t.clock t.port_max_idle_time
14881499
end
14891500

14901501
end

src/hostnet/slirp.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type ('clock, 'vnet_switch) config = {
3131
mtu: int;
3232
host_names: Dns.Name.t list;
3333
clock: 'clock;
34+
port_max_idle_time: int;
3435
}
3536

3637
module Make

src/hostnet_test/slirp_stack.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ let config =
169169
mtu = 1500;
170170
host_names = [];
171171
clock;
172+
port_max_idle_time = 300;
172173
}
173174

174175
(* This is a hacky way to get a hancle to the server side of the stack. *)

src/ofs/active_config.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,18 @@ module Make(Time: Mirage_time_lwt.S)(FLOW: Mirage_flow_lwt.S) = struct
228228
| Some x -> Lwt.return x
229229
) vs
230230

231+
open Astring
232+
231233
let int t ~default path =
232234
string t ~default:(string_of_int default) path
233235
>>= fun strings ->
234-
let parse s = Lwt.return (try int_of_string s with _ -> default) in
236+
let parse s = Lwt.return (try int_of_string @@ String.trim ~drop:Char.Ascii.is_white s with _ -> default) in
235237
changes @@ map parse strings
236238

237239
let bool t ~default path =
238240
string t ~default:(string_of_bool default) path
239241
>>= fun strings ->
240-
let parse s = Lwt.return (try bool_of_string s with _ -> default) in
242+
let parse s = Lwt.return (try bool_of_string @@ String.trim ~drop:Char.Ascii.is_white s with _ -> default) in
241243
changes @@ map parse strings
242244

243245
end

0 commit comments

Comments
 (0)