1 (** standalone DHT node *)
5 let bracket res destroy k
=
6 let x = try k res
with exn
-> destroy res
; raise exn
in
10 let with_open_in_bin file
= bracket (open_in_bin file
) close_in_noerr
11 let with_open_out_bin file
= bracket (open_out_bin file
) close_out_noerr
13 let load file
: Kademlia.table
= with_open_in_bin file
Marshal.from_channel
15 let store file
(t
:Kademlia.table
) =
16 let temp = file ^
".tmp" in
18 with_open_out_bin temp (fun ch
-> Marshal.to_channel ch t
[]; Unix2.fsync
(Unix.descr_of_out_channel ch
));
21 lprintf_nl ~exn
"write to %S failed" file
; Sys.remove
temp
25 match String2.split s '
:'
with
26 | [addr
;port
] -> addr
, int_of_string port
27 | _
-> raise Not_found
29 Printf.eprintf
"E: bad peer %S, expecting <addr>:<port>\n%!" s
;
32 let init file
= try load file
with _
-> Kademlia.create
()
36 "FA959F240D5859CAC30F32ECD21BD89F576481F0";
37 "BDE98D04AB6BD6E8EA7440F82870E5191E130A84";
38 "857224361969AE12066166539538F07BD5EF48B4";
39 "81F643A195BBE3BB1DE1AC9184B9F84D74A37EFF";
40 "7CC9963D90B54DF1710469743C1B43E0E20489C0";
41 "C2C65A1AA5537406183F4D815C77A2A578B00BFB";
42 "72F5A608AFBDF6111E5A86B337E9FC27D6020663";
43 "FE73D74660695208F3ACD221B7A9A128A3D36D47";
46 let id = Kademlia.H.of_hexa
ids.(Random.int (Array.length
ids)) in
47 query_peers dht
id (fun node token peers
->
48 lprintf_nl
"run_queries : %s returned %d peers : %s"
49 (show_node node
) (List.length peers
) (strl
Kademlia.show_addr peers
))
54 match List.tl
(Array.to_list
Sys.argv
) with
55 | file
::port
::peers
->
56 let peers = List.map
parse_peer peers in
57 let bw = UdpSocket.new_bandwidth_controler
58 (TcpBufferedSocket.create_write_bandwidth_controler
"UNLIMIT" 0) in
59 let dht = start
(init file
) (int_of_string port
) bw in
60 let finish () = store file
dht.M.rt
; stop
dht; exit
0 in
61 Sys.set_signal
Sys.sigint
(Sys.Signal_handle
(fun _
-> show
dht; finish ()));
62 Sys.set_signal
Sys.sigterm
(Sys.Signal_handle
(fun _
-> show
dht; finish ()));
63 Sys.set_signal
Sys.sighup
(Sys.Signal_handle
(fun _
-> show
dht));
64 BasicSocket.add_infinite_timer
1800. (fun () -> run_queries dht);
65 BasicSocket.add_infinite_timer
3600. (fun () -> store file
dht.M.rt
);
66 let routers = ["router.bittorrent.com", 8991] @ peers in
67 bootstrap
dht ~
routers;
69 | _
-> Printf.eprintf
"Usage : %s <storage> <port> [<peer_addr:port>]*\n" Sys.argv
.(0)
71 exn
-> lprintf_nl
"main : %s" (Printexc.to_string exn
)