summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/thibaut/Makefile4
-rw-r--r--sources/thibaut/client.ml138
-rw-r--r--sources/thibaut/clientGlobals.ml8
-rw-r--r--sources/thibaut/clientMesh.ml30
-rw-r--r--sources/thibaut/clientMessages.ml0
5 files changed, 126 insertions, 54 deletions
diff --git a/sources/thibaut/Makefile b/sources/thibaut/Makefile
index 88a23d9..5652865 100644
--- a/sources/thibaut/Makefile
+++ b/sources/thibaut/Makefile
@@ -3,7 +3,7 @@ OCAMLOPT=ocamlopt
OCAMLDEP=ocamldep
INCLUDES=
OCAMLFLAGS=$(INCLUDES) -annot
-SRCS=simulator.ml trace.ml gentrace.ml pacemaker.ml globals.ml compattrace.ml tracestats.ml mesh.ml graph.ml client.ml clientGlobals.ml
+SRCS=simulator.ml trace.ml gentrace.ml pacemaker.ml globals.ml compattrace.ml tracestats.ml mesh.ml graph.ml client.ml clientMesh.ml clientGlobals.ml
BUILDDIR=build
DEPEND=.depend
LIBS=str unix
@@ -18,7 +18,7 @@ $(BUILDDIR):
client: $(BUILDDIR) $(BUILDDIR)/client
$(BUILDDIR)/client: client.cmx
- $(OCAMLOPT) -o $@ $(OCAMLFLAGS) $(LIBSOPT) clientGlobals.cmx client.cmx
+ $(OCAMLOPT) -o $@ $(OCAMLFLAGS) $(LIBSOPT) clientGlobals.cmx clientMesh.cmx client.cmx
tracestats.opt: $(BUILDDIR) $(BUILDDIR)/tracestats
diff --git a/sources/thibaut/client.ml b/sources/thibaut/client.ml
index 39aea36..10450f4 100644
--- a/sources/thibaut/client.ml
+++ b/sources/thibaut/client.ml
@@ -1,5 +1,6 @@
open Unix
open ClientGlobals
+open ClientMesh
let port = ref 54321
let max_length = 10000
@@ -8,13 +9,17 @@ let version = "0.1"
let server = ref false
let id_file = ref "id.conf"
let generate = ref false
+let degree = ref 10
+let accuracy = ref 10.
let arg_list = Arg.align [
"--port", Arg.Set_int port, " <n> listening port";
"--conf", Arg.Set_string config_file, " <filename> configuration file";
"--server", Arg.Set server, " launch the client as a server";
"--id", Arg.Set_string id_file, " <filename> id file";
- "--genid", Arg.Set generate, " generate the id file"
+ "--genid", Arg.Set generate, " generate the id file";
+ "--degree", Arg.Set_int degree, " <n> number of neighbours";
+ "--accuracy", Arg.Set_float accuracy, " <n> number of minutes between rounds";
]
let usage = Printf.sprintf "usage: %s [OPTIONS]" Sys.argv.(0)
@@ -23,22 +28,33 @@ let process_message s =
let message = Marshal.from_string s 0 in
()
+let safe_open f filename =
+ try
+ f filename
+ with
+ | Sys_error s -> Printf.eprintf "Could not open file: %s.\n" s; exit 1
+
+let send_message socket message addr =
+ let raw = Marshal.to_string message [] in
+ ignore( sendto
+ socket (Marshal.to_string message [])
+ 0 (String.length raw) [] addr
+ )
+
+let init_round time = ()
+let init_pulse time = ()
+let seed_reply time = ()
+let filter_peers () = ()
let _ =
Printf.printf "Pacemaker client v%s\n%!" version;
Arg.parse arg_list (fun _ -> ()) usage;
- let my_address = (gethostbyname(gethostname())).h_addr_list.(0) in
+ let my_addr = (gethostbyname(gethostname())).h_addr_list.(0) in
- let _ =
+ let _ =
if !generate then begin
- let id_oc =
- try
- open_out !id_file
- with
- Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!"
- !id_file s; exit 1
- in
+ let id_oc = safe_open open_out !id_file in
Random.self_init ();
Printf.fprintf id_oc "%d" (Random.int 500000000);
Printf.printf "Id generated in file %s\n%!" !id_file;
@@ -47,65 +63,83 @@ let _ =
end
in
- let id_ic =
- try
- open_in !id_file
- with
- Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!"
- !id_file s; exit 1
- in
-
+ let id_ic = safe_open open_in !id_file in
let my_id = Scanf.fscanf id_ic "%d" (fun x -> x) in
-
- let conf_ic =
- try
- open_in !config_file
- with
- Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!"
- !config_file s; exit 1
- in
-
- let server_address, server_port =
- Scanf.fscanf conf_ic "%s\n%d" (fun a b -> a,b)
- in
-
+ let conf_ic = safe_open open_in !config_file in
+ let root_addr, root_port = Scanf.fscanf conf_ic "%s\n%d" (fun a b -> a,b) in
let _ = close_in conf_ic; close_in id_ic in
let socket = socket PF_INET SOCK_DGRAM 0 in
- let address = ADDR_INET(
- my_address,
+ let addr = ADDR_INET(
+ my_addr,
!port
) in
- let server_address = ADDR_INET(
- inet_addr_of_string server_address,
- server_port
+ let root_addr = ADDR_INET(
+ inet_addr_of_string root_addr,
+ root_port
) in
let _ = try
- bind socket address
+ bind socket addr
with
| Unix_error(e,s1,s2) ->
- Printf.eprintf "Could not bind socket on port %d: %s in %s %s\n%!"
+ Printf.eprintf "Could not bind socket on port %d: %s in %s %s\n%!"
!port (error_message e) s1 s2;
exit 1
in
+
+ Printf.printf "Now listening on UDP port %d\n%!" !port;
+ let slot_array = SlotArray.make !degree in
+
+ let reply_tick = 30. in
+ let mesh_tick = 30. in
+ let seed_tick = !accuracy/.2. in
+ let time = Unix.gettimeofday() in
+ let next_round = ref (time +. !accuracy) in
+ let next_pulse = ref (!next_round +. seed_tick) in
+ let next_seed = ref (time +. reply_tick) in
+ let next_mesh = ref (time +. mesh_tick) in
while true do
- let a,b,c = select [socket] [] [] 1. in
- match a with
- | [] -> ()
- | t::q ->
- let buff = String.create max_length in
- let len, addr = recvfrom t buff 0 max_length [] in
- let addr_string = match addr with
- | ADDR_INET(iaddr,port) -> Printf.sprintf "%s:%d"
- (string_of_inet_addr iaddr) port
- | _ -> ""
- in
- process_message (String.sub buff 0 len);
- Printf.printf "Received from %s: %s\n%!" addr_string
- (String.sub buff 0 len)
+ let time = Unix.gettimeofday() in
+
+ if !server && (time > !next_round) then begin
+ init_round time;
+ next_round := time +. !accuracy;
+ next_pulse := !next_round +. seed_tick;
+ end;
+
+ if !server && (time > !next_pulse) then begin
+ init_pulse time;
+ next_pulse := !next_pulse +. !accuracy;
+ end;
+
+ if (not !server) && (time > !next_seed) then begin
+ seed_reply time;
+ next_seed := !next_seed +. reply_tick
+ end;
+
+ if time > !next_mesh then begin
+ next_mesh := !next_mesh +. mesh_tick;
+ filter_peers ();
+ end;
+
+ let a,b,c = select [socket] [] [] 1. in
+ match a with
+ | [] -> ()
+ | t::q ->
+ let buff = String.create max_length in
+ let len, addr = recvfrom t buff 0 max_length [] in
+ let addr_string = match addr with
+ | ADDR_INET(iaddr,port) -> Printf.sprintf "%s:%d"
+ (string_of_inet_addr iaddr) port
+ | _ -> ""
+ in
+ process_message (String.sub buff 0 len);
+ Printf.printf "Received from %s: %s\n%!" addr_string
+ (String.sub buff 0 len)
+
done
diff --git a/sources/thibaut/clientGlobals.ml b/sources/thibaut/clientGlobals.ml
index be72604..a07715d 100644
--- a/sources/thibaut/clientGlobals.ml
+++ b/sources/thibaut/clientGlobals.ml
@@ -11,5 +11,13 @@ type message_content =
type message = {
id : user_id;
+ version : string;
content : message_content;
}
+
+type neighbour = {
+ id : user_id;
+ last_seen : float;
+ addr : sockaddr;
+}
+
diff --git a/sources/thibaut/clientMesh.ml b/sources/thibaut/clientMesh.ml
new file mode 100644
index 0000000..6a63017
--- /dev/null
+++ b/sources/thibaut/clientMesh.ml
@@ -0,0 +1,30 @@
+open ClientGlobals
+
+module SlotArray : sig
+ type t
+ type slot = Peer of neighbour | Empty
+ val make : int -> t
+ val full : t -> bool
+end = struct
+
+ type slot = Peer of neighbour | Empty
+
+ type t = {
+ capacity : int;
+ mutable length : int;
+ array : slot array
+ }
+
+ let make degree = {
+ capacity = degree;
+ length = 0;
+ array = Array.make degree Empty
+ }
+
+ let full sa = sa.length = sa.capacity
+
+ let add sa neighbour =
+ let length = sa.length in
+ if not (full sa) then
+ sa.array.(length) <- neighbour
+end
diff --git a/sources/thibaut/clientMessages.ml b/sources/thibaut/clientMessages.ml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sources/thibaut/clientMessages.ml