Source file Compile_Server.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
open Core
open Async
open Cohttp_async
open Frenetic_netkat.Syntax
module Server = Cohttp_async.Server
open Common
module Comp = Frenetic_netkat.Local_compiler
let policy = ref Frenetic_netkat.Syntax.drop
let current_compiler_options = ref { Comp.default_compiler_options with optimize = false }
let compile_respond pol =
let (time, tbls) = profile (fun () ->
let fdd = Comp.compile ~options:!current_compiler_options pol in
let sws =
let sws = Frenetic_netkat.Semantics.switches_of_policy pol in
if List.length sws = 0 then [0L] else sws in
List.map sws ~f:(fun sw ->
(sw, Comp.to_table ~options:!current_compiler_options sw fdd))) in
let json_tbls = List.map tbls ~f:(fun (sw, tbl) ->
`Assoc [("switch_id", `Int (Int64.to_int_exn sw));
("tbl", Frenetic_netkat.Json.flowTable_to_json tbl)]) in
let resp = Yojson.Basic.to_string ~std:true (`List json_tbls) in
let = Cohttp.Header.init_with
"X-Compile-Time" (Float.to_string time) in
Cohttp_async.Server.respond_string ~headers resp
let handle_request
~(body : Cohttp_async.Body.t)
(client_addr : Socket.Address.Inet.t)
(request : Request.t) : Server.response Deferred.t =
match request.meth, extract_path request with
| `POST, ["compile_pretty"] -> handle_parse_errors body
parse_update
compile_respond
| `POST, ["compile"] ->
printf "POST /compile";
handle_parse_errors body
(fun body ->
Body.to_string body >>= fun str ->
return (Frenetic_netkat.Json.pol_of_json_string str))
compile_respond
| `POST, ["update"] ->
printf "POST /update";
handle_parse_errors body parse_update_json
(fun p ->
policy := p;
Cohttp_async.Server.respond `OK)
| `GET, [switchId; "flow_table"] ->
let sw = Int64.of_string switchId in
Comp.compile ~options:!current_compiler_options !policy |>
Comp.to_table ~options:!current_compiler_options sw |>
Frenetic_netkat.Json.flowTable_to_json |>
Yojson.Basic.to_string ~std:true |>
Cohttp_async.Server.respond_string
| `POST, ["config"] ->
printf "POST /config";
handle_parse_errors body parse_config_json
(fun conf -> current_compiler_options := conf; Cohttp_async.Server.respond `OK)
| `GET, ["config"] ->
printf "GET /config";
Comp.options_to_json_string !current_compiler_options |>
Cohttp_async.Server.respond_string
| _, _ ->
printf "Malformed request from cilent";
Cohttp_async.Server.respond `Not_found
let listen ?(port=9000) () =
Cohttp_async.Server.create
~on_handler_error:`Raise
(Tcp.Where_to_listen.of_port port)
handle_request
|> ignore
let main (http_port : int) () : unit =
listen ~port:http_port ()