61 |
open BTGlobals |
open BTGlobals |
62 |
open BTComplexOptions |
open BTComplexOptions |
63 |
open BTChooser |
open BTChooser |
64 |
|
open BTStats |
65 |
open TcpMessages |
open TcpMessages |
66 |
|
|
67 |
(* prints a new logline with date, module and starts newline *) |
(* prints a new logline with date, module and starts newline *) |
128 |
("compact","1") :: |
("compact","1") :: |
129 |
args |
args |
130 |
in |
in |
131 |
|
let args = if !!send_key then |
132 |
|
("key", Sha1.to_hexa !!client_uid) :: args else args |
133 |
|
in |
134 |
let args = if !!numwant > -1 then |
let args = if !!numwant > -1 then |
135 |
("numwant", string_of_int !!numwant) :: args else args |
("numwant", string_of_int !!numwant) :: args else args |
136 |
in |
in |
146 |
|| t.tracker_last_conn + t.tracker_interval < last_time() |
|| t.tracker_last_conn + t.tracker_interval < last_time() |
147 |
|| ( file.file_clients_num < !!ask_tracker_threshold |
|| ( file.file_clients_num < !!ask_tracker_threshold |
148 |
&& (file_state file) == FileDownloading |
&& (file_state file) == FileDownloading |
149 |
&& t.tracker_last_conn + !!min_tracker_reask_interval < last_time() ) |
&& (if t.tracker_min_interval > !!min_tracker_reask_interval then |
150 |
|
t.tracker_last_conn + t.tracker_min_interval < last_time() |
151 |
|
else |
152 |
|
t.tracker_last_conn + !!min_tracker_reask_interval < last_time() )) |
153 |
then |
then |
154 |
begin |
begin |
155 |
if !verbose_msg_servers then |
(* if we already tried to connect but failed, remove tracker *) |
156 |
lprintf_nl () "get_sources_from_tracker: tracker_connected:%s last_clients:%i last_conn-last_time:%i file: %s" |
if file.file_tracker_connected && t.tracker_last_clients_num = 0 && |
157 |
(string_of_bool file.file_tracker_connected) t.tracker_last_clients_num |
t.tracker_last_conn < 1 then begin |
158 |
(t.tracker_last_conn - last_time()) file.file_name; |
if !verbose_msg_servers then |
159 |
|
lprintf_nl () "Request error from tracker: removing %s" t.tracker_url; |
160 |
let module H = Http_client in |
remove_tracker t.tracker_url file |
161 |
let url = t.tracker_url in |
end |
162 |
let r = { |
(* Send request to tracker *) |
163 |
H.basic_request with |
else begin |
164 |
H.req_url = Url.of_string ~args: args url; |
let args = if String.length t.tracker_id > 0 then |
165 |
H.req_proxy = !CommonOptions.http_proxy; |
("trackerid", t.tracker_id) :: args else args |
166 |
H.req_user_agent = |
in |
167 |
Printf.sprintf "MLdonkey/%s" Autoconf.current_version; |
let args = if String.length t.tracker_key > 0 then |
168 |
} in |
("key", t.tracker_key) :: args else args |
169 |
|
in |
170 |
if !verbose_msg_servers then |
if !verbose_msg_servers then |
171 |
lprintf_nl () "Request sent to tracker %s for file: %s" |
lprintf_nl () "get_sources_from_tracker: tracker_connected:%s id:%s key:%s last_clients:%i last_conn-last_time:%i file: %s" |
172 |
t.tracker_url file.file_name; |
(string_of_bool file.file_tracker_connected) |
173 |
H.wget r |
t.tracker_id t.tracker_key t.tracker_last_clients_num |
174 |
(fun fileres -> |
(t.tracker_last_conn - last_time()) file.file_name; |
175 |
t.tracker_last_conn <- last_time (); |
|
176 |
file.file_tracker_connected <- true; |
let module H = Http_client in |
177 |
f t fileres |
let url = t.tracker_url in |
178 |
) |
let r = { |
179 |
|
H.basic_request with |
180 |
|
H.req_url = Url.of_string ~args: args url; |
181 |
|
H.req_proxy = !CommonOptions.http_proxy; |
182 |
|
H.req_user_agent = |
183 |
|
Printf.sprintf "MLdonkey/%s" Autoconf.current_version; |
184 |
|
} in |
185 |
|
|
186 |
|
if !verbose_msg_servers then |
187 |
|
lprintf_nl () "Request sent to tracker %s for file: %s" |
188 |
|
t.tracker_url file.file_name; |
189 |
|
H.wget r |
190 |
|
(fun fileres -> |
191 |
|
t.tracker_last_conn <- last_time (); |
192 |
|
file.file_tracker_connected <- true; |
193 |
|
f t fileres) |
194 |
|
end |
195 |
end |
end |
196 |
|
|
197 |
else |
else |
198 |
if !verbose_msg_servers then |
if !verbose_msg_servers then |
199 |
lprintf_nl () "Request NOT sent to tracker %s - remaning: %d file: %s" |
lprintf_nl () "Request NOT sent to tracker %s - next request in %ds for file: %s" |
200 |
t.tracker_url (t.tracker_interval - (last_time () - t.tracker_last_conn)) file.file_name |
t.tracker_url (t.tracker_interval - (last_time () - t.tracker_last_conn)) file.file_name |
201 |
) file.file_trackers |
) file.file_trackers; |
202 |
|
(* if there is no tracker left, do something ? *) |
203 |
|
if List.length file.file_trackers = 0 then |
204 |
|
if !verbose_msg_servers then |
205 |
|
lprintf_nl () "No trackers left ..." |
206 |
|
|
207 |
(** In this function we decide which peers will be |
(** In this function we decide which peers will be |
208 |
uploaders. We send a choke message to current uploaders |
uploaders. We send a choke message to current uploaders |
261 |
(* List.iter (fun r -> Int64Swarmer.free_range r) c.client_ranges; *) |
(* List.iter (fun r -> Int64Swarmer.free_range r) c.client_ranges; *) |
262 |
set_client_disconnected c reason; |
set_client_disconnected c reason; |
263 |
let file = c.client_file in |
let file = c.client_file in |
264 |
|
(try if c.client_good then count_seen c with _ -> ()); |
265 |
(* this is not useful already done in the match |
(* this is not useful already done in the match |
266 |
(try close sock reason with _ -> ()); *) |
(try close sock reason with _ -> ()); *) |
267 |
(*---------not needed ?? VvvvvV--------------- |
(*---------not needed ?? VvvvvV--------------- |
695 |
x y |
x y |
696 |
with Not_found -> |
with Not_found -> |
697 |
if not (Int64Swarmer.check_finished swarmer) && !verbose_hidden_errors then |
if not (Int64Swarmer.check_finished swarmer) && !verbose_hidden_errors then |
698 |
lprintf_nl () "BTClient.get_from_client ERROR: can't find a block to download and file is not yet finished..." |
lprintf_nl () |
699 |
|
"BTClient.get_from_client ERROR: can't find a block to download and file is not yet finished for file : %s..." file.file_name |
700 |
|
|
701 |
|
|
702 |
(** In this function we match a message sent by a client |
(** In this function we match a message sent by a client |
763 |
let new_downloaded = |
let new_downloaded = |
764 |
Int64Swarmer.downloaded swarmer in |
Int64Swarmer.downloaded swarmer in |
765 |
|
|
766 |
(*Update rate and ammount of data received from client*) |
(*Update rate and amount of data received from client*) |
767 |
c.client_downloaded <- c.client_downloaded ++ |
c.client_downloaded <- c.client_downloaded ++ |
768 |
(new_downloaded -- old_downloaded); |
(new_downloaded -- old_downloaded); |
769 |
Rate.update c.client_downloaded_rate (float_of_int len); |
Rate.update c.client_downloaded_rate (float_of_int len); |
770 |
|
(* update the stats *) |
771 |
|
let len64 = Int64.of_int len in |
772 |
|
count_download c file len64; |
773 |
if !verbose_msg_clients then |
if !verbose_msg_clients then |
774 |
(match c.client_ranges_sent with |
(match c.client_ranges_sent with |
775 |
[] -> lprintf_nl () "EMPTY Ranges!" |
[] -> lprintf_nl () "EMPTY Ranges !!!" |
776 |
| (p1,p2,r) :: _ -> |
| (p1,p2,r) :: _ -> |
777 |
let (x,y) = Int64Swarmer.range_range r in |
let (x,y) = Int64Swarmer.range_range r in |
778 |
lprintf_nl () "Received %Ld [%d] %Ld-%Ld[%Ld-%Ld] -> %Ld" |
lprintf_nl () "Received %Ld [%d] %Ld-%Ld[%Ld-%Ld] -> %Ld" |
779 |
position len |
position len |
807 |
send_client c Unchoke; |
send_client c Unchoke; |
808 |
end; |
end; |
809 |
|
|
810 |
(* Check if the client is still interesting for us... *) |
(* Check if the client is still interesting for us... *) |
811 |
check_if_interesting file c |
check_if_interesting file c |
812 |
|
|
813 |
| PeerID p -> |
| PeerID p -> |
814 |
|
c.client_brand <- (parse_brand p); |
815 |
c.client_software <- (parse_software p); |
c.client_software <- (parse_software p); |
816 |
|
(* TODO : enable it |
817 |
|
c.client_release <- (parse_release p c.client_brand); |
818 |
|
*) |
819 |
c.client_uid <- Sha1.direct_of_string p; |
c.client_uid <- Sha1.direct_of_string p; |
820 |
(* Disconnect if that is ourselves. *) |
(* Disconnect if that is ourselves. *) |
821 |
if c.client_uid = !!client_uid then disconnect_client c Closed_by_user |
if c.client_uid = !!client_uid then disconnect_client c Closed_by_user |
1189 |
try |
try |
1190 |
match c.client_sock with |
match c.client_sock with |
1191 |
| Connection sock -> () |
| Connection sock -> () |
1192 |
(*i think this one is not really usefull for debugging |
(*i think this one is not realy usefull for debugging |
1193 |
lprintf "[BT] : RESUME: Client is already connected\n"; *) |
lprintf_nl "[BT]: RESUME: Client is already connected"; *) |
1194 |
| _ -> |
| _ -> |
1195 |
(try |
(try |
1196 |
(*test if we can connect client according to the its |
(*test if we can connect client according to the its |
1197 |
connection_control. |
connection_control. |
1198 |
Currently the delay between two try is 120 seconds. |
Currently the delay between two try is 120 seconds. |
1199 |
*) |
*) |
1200 |
if connection_can_try c.client_connection_control then |
if connection_can_try c.client_connection_control then |
1201 |
connect_client c |
connect_client c |
1202 |
else |
else |
1203 |
print_control c.client_connection_control |
print_control c.client_connection_control |
1204 |
with _ -> ()) |
with _ -> ()) |
1205 |
with e -> () |
with e -> |
1206 |
(* lprintf "Exception %s in resume_clients\n" (Printexc2.to_string e) *) |
if !verbose_connect then |
1207 |
|
lprintf_nl () "Exception %s in resume_clients" (Printexc2.to_string e) |
1208 |
) file.file_clients |
) file.file_clients |
1209 |
|
|
1210 |
|
(** Check if the value replied by the tracker is correct. |
1211 |
|
@param key the name of the key |
1212 |
|
@param n the value to check |
1213 |
|
@param url Url of the tracker |
1214 |
|
@param name the name of the file |
1215 |
|
*) |
1216 |
|
let chk_keyval key n url name = |
1217 |
|
let int_n = (Int64.to_int n) in |
1218 |
|
if !verbose_msg_clients then |
1219 |
|
lprintf_nl () "Reply from %s in file: %s has %s: %d" url name key int_n; |
1220 |
|
if int_n > -1 then |
1221 |
|
int_n |
1222 |
|
else begin |
1223 |
|
lprintf_nl () "Reply from %s in file: %s has an invalid %s value: %d" url name key int_n; |
1224 |
|
0 |
1225 |
|
end |
1226 |
|
|
1227 |
|
|
1228 |
(** In this function we initiate a connection to the file tracker |
(** In this function we initiate a connection to the file tracker |
1229 |
to get sources. |
to get sources. |
1235 |
*) |
*) |
1236 |
let get_sources_from_tracker file = |
let get_sources_from_tracker file = |
1237 |
let f t filename = |
let f t filename = |
1238 |
(*This is the function which will be called by the http client |
(*This is the function which will be called by the http client |
1239 |
for parsing the response*) |
for parsing the response |
1240 |
let v = Bencode.decode (File.to_string filename) in |
*) |
1241 |
|
let tracker_reply = |
1242 |
|
try |
1243 |
|
File.to_string filename |
1244 |
|
with e -> lprintf_nl () "Empty reply from tracker"; "" |
1245 |
|
in |
1246 |
|
let v = |
1247 |
|
match tracker_reply with |
1248 |
|
| "" -> |
1249 |
|
if !verbose_connect then |
1250 |
|
lprintf_nl () "Empty reply from tracker"; |
1251 |
|
Bencode.decode "" |
1252 |
|
| _ -> Bencode.decode tracker_reply |
1253 |
|
in |
1254 |
t.tracker_interval <- 600; |
t.tracker_interval <- 600; |
1255 |
|
t.tracker_min_interval <- 600; |
1256 |
t.tracker_last_clients_num <- 0; |
t.tracker_last_clients_num <- 0; |
1257 |
match v with |
match v with |
1258 |
Dictionary list -> |
Dictionary list -> |
1259 |
List.iter (fun (key,value) -> |
List.iter (fun (key,value) -> |
1260 |
match (key, value) with |
match (key, value) with |
|
String "interval", Int n -> |
|
|
t.tracker_interval <- Int64.to_int n |
|
1261 |
| String "failure reason", String failure -> |
| String "failure reason", String failure -> |
1262 |
lprintf_nl () "Failure from Tracker %s in file: %s Reason: %s" t.tracker_url file.file_name failure |
(* On failure, remove the faulty tracker from file.file_trackers list *) |
1263 |
| String "complete", Int n -> () (*TODO we should put these two in some var. and perhaps display them in the gui*) |
remove_tracker t.tracker_url file; |
1264 |
| String "incomplete", Int n -> () |
lprintf_nl () "Failure from Tracker %s in file: %s Reason: %s\nBT: Tracker %s removed for failure" |
1265 |
|
t.tracker_url file.file_name failure t.tracker_url |
1266 |
|
| String "warning message", String warning -> |
1267 |
|
lprintf_nl () "Warning from Tracker %s in file: %s Reason: %s" t.tracker_url file.file_name warning |
1268 |
|
| String "interval", Int n -> |
1269 |
|
t.tracker_interval <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name; |
1270 |
|
(* in case we don't receive "min interval" *) |
1271 |
|
if t.tracker_min_interval > t.tracker_interval then |
1272 |
|
t.tracker_min_interval <- t.tracker_interval |
1273 |
|
| String "min interval", Int n -> |
1274 |
|
t.tracker_min_interval <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name; |
1275 |
|
(* make sure "min interval" is always < or equal to "interval" *) |
1276 |
|
if t.tracker_min_interval > t.tracker_interval then |
1277 |
|
t.tracker_min_interval <- t.tracker_interval |
1278 |
|
| String "downloaded", Int n -> |
1279 |
|
t.tracker_torrent_downloaded <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name |
1280 |
|
| String "complete", Int n |
1281 |
|
| String "done peers", Int n -> |
1282 |
|
t.tracker_torrent_complete <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name |
1283 |
|
| String "incomplete", Int n -> |
1284 |
|
t.tracker_torrent_incomplete <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name; |
1285 |
|
(* if complete > 0 and we receive incomplete we probably won't receive num_peers so we simulate it below *) |
1286 |
|
if t.tracker_torrent_complete > 0 then |
1287 |
|
t.tracker_torrent_total_clients_count <- (t.tracker_torrent_complete + t.tracker_torrent_incomplete); |
1288 |
|
| String "num peers", Int n -> |
1289 |
|
t.tracker_torrent_total_clients_count <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name; |
1290 |
|
(* if complete > 0 and we receive num_peers we probably won't receive incomplete so we simulate it below *) |
1291 |
|
if t.tracker_torrent_complete > 0 then |
1292 |
|
t.tracker_torrent_incomplete <- (t.tracker_torrent_total_clients_count - t.tracker_torrent_complete); |
1293 |
|
| String "last", Int n -> |
1294 |
|
t.tracker_torrent_last_dl_req <- chk_keyval (Bencode.print key) n t.tracker_url file.file_name |
1295 |
|
| String "key", String n -> |
1296 |
|
t.tracker_key <- n; |
1297 |
|
if !verbose_msg_clients then |
1298 |
|
lprintf_nl () "%s in file: %s has key: %s" t.tracker_url file.file_name n |
1299 |
|
| String "tracker id", String n -> |
1300 |
|
t.tracker_id <- n; |
1301 |
|
if !verbose_msg_clients then |
1302 |
|
lprintf_nl () "%s in file: %s has tracker id %s" t.tracker_url file.file_name n |
1303 |
|
|
1304 |
| String "peers", List list -> |
| String "peers", List list -> |
1305 |
List.iter (fun v -> |
List.iter (fun v -> |
1306 |
match v with |
match v with |
1420 |
c.client_allowed_to_write <- c.client_allowed_to_write -- len; |
c.client_allowed_to_write <- c.client_allowed_to_write -- len; |
1421 |
c.client_uploaded <- c.client_uploaded ++ len; |
c.client_uploaded <- c.client_uploaded ++ len; |
1422 |
let len = Int64.to_int len in |
let len = Int64.to_int len in |
1423 |
(* CommonUploads.consume_bandwidth (len/2); *) |
CommonUploads.consume_bandwidth len; |
1424 |
(* lprintf "Unix32.read: offset %Ld len %d\n" offset len; *) |
(* lprintf "Unix32.read: offset %Ld len %d\n" offset len; *) |
1425 |
Unix32.read (file_fd file) offset upload_buffer 0 len; |
Unix32.read (file_fd file) offset upload_buffer 0 len; |
1426 |
(*update uploade rate from len bytes*) |
(* update upload rate from len bytes *) |
1427 |
Rate.update c.client_upload_rate (float_of_int len); |
Rate.update c.client_upload_rate (float_of_int len); |
1428 |
file.file_uploaded <- file.file_uploaded ++ (Int64.of_int len); |
file.file_uploaded <- file.file_uploaded ++ (Int64.of_int len); |
1429 |
let _ = |
let _ = |
1430 |
|
(* update stats *) |
1431 |
|
count_filerequest c; |
1432 |
match file.file_shared with |
match file.file_shared with |
1433 |
None -> () |
None -> () |
1434 |
| Some s -> |
| Some s -> |
1439 |
in |
in |
1440 |
(* lprintf "sending piece\n"; *) |
(* lprintf "sending piece\n"; *) |
1441 |
send_client c (Piece (num, pos, upload_buffer, 0, len)); |
send_client c (Piece (num, pos, upload_buffer, 0, len)); |
1442 |
|
(* update stats *) |
1443 |
|
let uploaded = Int64.of_int len in |
1444 |
|
count_upload c file uploaded; |
1445 |
iter_upload sock c |
iter_upload sock c |
1446 |
end else |
end else |
1447 |
begin |
begin |