2012-03-07 18:23:41 +00:00
|
|
|
(* Copyright 2012 Tony Garnock-Jones <tonygarnockjones@gmail.com>. *)
|
|
|
|
|
|
|
|
(* This file is part of Ocamlmsg. *)
|
|
|
|
|
|
|
|
(* Ocamlmsg is free software: you can redistribute it and/or modify it *)
|
|
|
|
(* under the terms of the GNU General Public License as published by the *)
|
|
|
|
(* Free Software Foundation, either version 3 of the License, or (at your *)
|
|
|
|
(* option) any later version. *)
|
|
|
|
|
|
|
|
(* Ocamlmsg is distributed in the hope that it will be useful, but *)
|
|
|
|
(* WITHOUT ANY WARRANTY; without even the implied warranty of *)
|
|
|
|
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *)
|
|
|
|
(* General Public License for more details. *)
|
|
|
|
|
|
|
|
(* You should have received a copy of the GNU General Public License *)
|
|
|
|
(* along with Ocamlmsg. If not, see <http://www.gnu.org/licenses/>. *)
|
|
|
|
|
2012-01-08 17:41:04 +00:00
|
|
|
open Unix
|
|
|
|
open Printf
|
|
|
|
open Thread
|
|
|
|
open Sexp
|
|
|
|
|
|
|
|
let send_error ch message details =
|
|
|
|
let m = Message.error (Str message, details) in
|
2012-03-03 23:04:28 +00:00
|
|
|
Log.warn "Sending error" [m];
|
2012-01-08 18:19:58 +00:00
|
|
|
ch m
|
2012-01-08 17:41:04 +00:00
|
|
|
|
|
|
|
let send_sexp_syntax_error ch explanation =
|
|
|
|
send_error ch explanation (Str "http://people.csail.mit.edu/rivest/Sexp.txt")
|
|
|
|
|
|
|
|
let dispatch_message n ch m =
|
|
|
|
match m with
|
|
|
|
| Message.Post (Str name, body, token) ->
|
|
|
|
Node.send_ignore name body
|
|
|
|
| Message.Subscribe (Str filter, sink, name, Str reply_sink, Str reply_name) ->
|
|
|
|
if Node.bind(filter, n)
|
|
|
|
then Node.post_ignore
|
|
|
|
reply_sink
|
|
|
|
(Str reply_name)
|
|
|
|
(Message.subscribe_ok (Str filter))
|
|
|
|
(Str "")
|
2012-01-08 19:48:07 +00:00
|
|
|
else Log.warn "Bind failed" [Str filter]
|
2012-01-08 19:54:20 +00:00
|
|
|
| Message.Unsubscribe (Str token) ->
|
|
|
|
if Node.unbind token
|
|
|
|
then ()
|
|
|
|
else Log.warn "Unbind failed" [Str token]
|
2012-01-08 17:41:04 +00:00
|
|
|
| _ ->
|
|
|
|
send_error ch "Message not understood" (Message.sexp_of_message m)
|
|
|
|
|
2012-03-03 23:04:28 +00:00
|
|
|
let issue_banner cin cout =
|
2012-01-08 17:41:04 +00:00
|
|
|
output_sexp_and_flush cout (Arr [Str "hop"; Str ""]);
|
|
|
|
output_sexp_and_flush cout
|
|
|
|
(Message.subscribe (Str (Node.local_container_name()),
|
|
|
|
Str "", Str "",
|
|
|
|
Str "", Str ""));
|
2012-03-03 23:04:28 +00:00
|
|
|
true
|
|
|
|
|
2012-03-04 17:12:20 +00:00
|
|
|
let relay_boot (peername, mtx, cin, cout) = (peername, mtx, cin, cout)
|
|
|
|
|
|
|
|
let relay_handler (_, mtx, _, cout) _ m =
|
2012-03-04 18:14:11 +00:00
|
|
|
Util.with_mutex mtx (output_sexp_and_flush cout) m
|
2012-03-03 23:04:28 +00:00
|
|
|
|
2012-03-04 17:12:20 +00:00
|
|
|
let relay_mainloop (peername, mtx, cin, cout) n =
|
2012-01-08 19:52:03 +00:00
|
|
|
let write_sexp = Util.with_mutex mtx (output_sexp cout) in
|
2012-01-08 17:41:04 +00:00
|
|
|
(try
|
|
|
|
while true do
|
2012-01-08 18:19:58 +00:00
|
|
|
dispatch_message n write_sexp (Message.message_of_sexp (Sexp.input_sexp cin))
|
2012-01-08 17:41:04 +00:00
|
|
|
done
|
|
|
|
with
|
|
|
|
| Sexp.Syntax_error explanation ->
|
2012-03-03 23:04:28 +00:00
|
|
|
(send_sexp_syntax_error write_sexp explanation;
|
|
|
|
Log.info "Disconnected relay for syntax error"
|
|
|
|
[Str (Connections.endpoint_name peername); Str explanation])
|
|
|
|
)
|
2012-01-08 17:41:04 +00:00
|
|
|
|
2012-03-03 23:04:28 +00:00
|
|
|
let start (s, peername) =
|
2012-03-04 17:12:20 +00:00
|
|
|
Connections.start_connection "relay" issue_banner
|
|
|
|
relay_boot relay_handler relay_mainloop (s, peername)
|