patch #7310
[mldonkey.git] / src / networks / donkey / donkeySupernode.ml
blob636878571d7300537ef9e69d0f7c344375202f34
1 (* Copyright 2001, 2002 Francois *)
2 (*
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 Supernode behavior for mldonkey...
23 A supernode acts as a server, but:
24 - it doesnot index its clients (since only mldonkey clients)
25 - it browses and index overnet+edonkey clients, without staying
26 connected. It specialized in clients whose MD4 are closed to
27 its MD4.
28 - mldonkey clients connect to 16 supernodes (the space of MD4 is
29 partitioned into 16 regions). 16 should be configurable.
32 open Printf2
33 open Md4
34 open Options
36 open CommonResult
37 open CommonTypes
38 open CommonOptions
39 open CommonRoom
40 open CommonShared
41 open CommonGlobals
42 open CommonFile
43 open CommonClient
44 open CommonComplexOptions
45 open GuiProto
46 open BasicSocket
47 open TcpBufferedSocket
48 open DonkeyMftp
49 open DonkeyProtoCom
50 open DonkeyTypes
51 open DonkeyOptions
52 open DonkeyComplexOptions
53 open DonkeyGlobals
55 type protocol =
57 (* Basic protocol between mldonkey clients *)
58 Connect of
59 (Ip.t * int * Md4.t) (* client identification *)
60 * int (* protocol version *)
61 * int (* supernodes needed (bitfield) *)
62 * int (* supernode activity *)
63 * int * int * int * int * int (* which NetworkInfo we need *)
64 | NetworkInfo of
65 bool (* accept as client *)
66 * (Ip.t * int * Md4.t) list (* browsable peers with MD4 for supernode *)
67 * (Ip.t * int) list (* browsable peers for supernode *)
68 * (Ip.t * int) list (* servers *)
69 * (Ip.t * int) list (* overnet peers *)
70 * (Ip.t * int * Md4.t) list (* supernodes *)
72 (* Localization of downloaded files *)
73 | RegisterDownloads of
74 (Md4.t * int32) list (* hash and size of downloads *)
75 | KnownSources of
76 Md4.t (* Md4 of file *)
77 * (Ip.t * int) list (* sources *)
79 (* Search of interesting files *)
80 | Search of
81 int * int (* search id and offset *)
82 * CommonTypes.query
83 | SearchReply of
84 int (* search id *)
85 * tagged_file list
88 type browsed_node = {
89 node_ip : Ip.t;
90 node_port : int;
91 mutable node_files : tagged_file list;
92 mutable node_md4 : Md4.t;
93 mutable node_last_browse : int;
96 let supernode_browse_handler node msg sock =
97 let module M = DonkeyProtoClient in
98 match msg with
100 | M.ViewFilesReplyReq t ->
101 lprintf "****************************************\n";
102 lprintf " BROWSE FILES REPLY \n";
103 let module Q = M.ViewFilesReply in
105 begin
107 node.node_files <- t;
108 List.iter (fun f ->
109 match result_of_file f.f_md4 f.f_tags with
110 None -> ()
111 | Some r ->
113 let r = DonkeyIndexer.index_result_no_filter r in
116 ) t;
117 with e ->
118 lprintf "Exception in ViewFilesReply %s\n"
119 (Printexc2.to_string e);
120 end;
121 node.node_last_browse <- last_time ();
122 close sock Closed_by_user
124 | M.ConnectReplyReq t ->
125 node.node_md4 <- t.M.Connect.md4;
127 | _ -> (* Don't care about other messages *)
130 let supernode_browse_client node =
131 let _ =
132 add_pending_connection connection_manager (fun token ->
134 let sock = TcpBufferedSocket.connect token "supernode browse client"
135 (Ip.to_inet_addr node.node_ip) node.node_port (fun _ _ -> ()) in
136 TcpBufferedSocket.set_read_controler sock download_control;
137 TcpBufferedSocket.set_write_controler sock upload_control;
138 set_rtimeout sock !!client_timeout;
139 set_handler sock (BASIC_EVENT RTIMEOUT) (fun s ->
140 close s Closed_for_timeout
142 let emule_proto = emule_proto () in
143 set_reader sock (DonkeyProtoCom.cut_messages
144 (DonkeyProtoClient.parse (emule_proto))
145 (supernode_browse_handler node));
146 let server_ip, server_port =
148 let s = DonkeyGlobals.last_connected_server () in
149 s.server_ip, s.server_port
150 with _ -> Ip.localhost, 4665
152 direct_client_sock_send (emule_proto) sock (
153 let module M = DonkeyProtoClient in
154 let module C = M.Connect in
155 M.ConnectReq {
156 C.hash_len = 16;
157 C.md4 = !!client_md4;
158 C.ip = client_ip None;
159 C.port = !!donkey_port;
160 C.tags = !client_to_client_tags;
161 C.server_info = Some (server_ip, server_port);
162 C.left_bytes = left_bytes;
164 direct_client_sock_send emule_proto sock (
165 let module M = DonkeyProtoClient in
166 let module C = M.ViewFiles in
167 M.ViewFilesReq C.t)
168 with _ -> ()
174 let client_connection_handler t event =
175 printf_string "[REMOTE CONN]";
176 match event with
177 TcpServerSocket.CONNECTION (s, Unix.ADDR_INET (from_ip, from_port)) ->
179 if can_open_connection () then
180 begin
182 let c = ref None in
183 let sock =
184 TcpBufferedSocket.create "donkey client connection" s
185 (client_handler2 c)
186 (*client_msg_to_string*)
188 init_connection sock;
190 (try
191 set_reader sock
192 (DonkeyProtoCom.client_handler2 c read_first_message
193 (client_to_client []));
195 with e -> lprintf "Exception %s in init_connection\n"
196 (Printexc2.to_string e));
197 with e ->
198 lprintf "Exception %s in client_connection_handler\n"
199 (Printexc2.to_string e);
200 Unix.close s
202 else begin
203 Unix.close s
204 end;
205 | _ ->