Hello,
Here is another patch. Combines several fixes, tell if you want them split
separately :
1) Don't request sources from tracker (set numwant=0) if we don't need them
e.g. 'stopped' event or when sharing
2) Prevent client from repeatedly sending 'started' events for shared files
3) Some indentation fixes (sorry, couldn't stand that)
4) Check that peer addresses, returned from tracker in compact format, are
valid and not blocked (same check as for non-compact format)
5) Show torrent info_hash in html ui
--
ygrek
http://ygrek.org.ua/
diff --git a/src/networks/bittorrent/TODO b/src/networks/bittorrent/TODO
new file mode 100644
index 0000000..deb5467
--- /dev/null
+++ b/src/networks/bittorrent/TODO
@@ -0,0 +1,2 @@
+* filter out duplicate trackers in metainfo (NB no port equals to :80 for http)
+* file_tracker_connected should be the property of tracker
diff --git a/src/networks/bittorrent/bTClients.ml b/src/networks/bittorrent/bTClients.ml
index ff27686..e26b045 100644
--- a/src/networks/bittorrent/bTClients.ml
+++ b/src/networks/bittorrent/bTClients.ml
@@ -84,10 +84,14 @@ let current_uploaders = ref ([] : BTTypes.client list)
Everything else will be ok for a second connection to the tracker.
Be careful to the spelling of this event
@param f The function used to parse the result of the connection.
- The function will get a file as an argument (@see
- get_sources_from_tracker for an example)
+ The function will get a file as an argument (@see talk_to_tracker
+ for an example)
+
+ If we have less than !!ask_tracker_threshold sources
+ and if we respect the file_tracker_interval then
+ we really ask sources to the tracker
*)
-let connect_trackers file event f =
+let connect_trackers file event need_sources f =
(* reset session statistics when sending 'started' event *)
if event = "started" then
@@ -118,8 +122,13 @@ let connect_trackers file event f =
in
let args = ("no_peer_id", "1") :: ("compact", "1") :: args in
- let args = if !!numwant > -1 then
- ("numwant", string_of_int !!numwant) :: args else args
+ let args =
+ if not need_sources then
+ ("numwant", "0") :: args
+ else if !!numwant > -1 then
+ ("numwant", string_of_int !!numwant) :: args
+ else
+ args
in
let args = if !!send_key then
("key", Sha1.to_hexa !!client_uid) :: args else args
@@ -143,18 +152,18 @@ let connect_trackers file event f =
else begin
(* if there is no tracker left, do something ? *)
if !verbose_msg_servers then
- lprintf_nl "No trackers left for %s, reenabling all of them..." (file_best_name (as_file file));
+ lprintf_nl "No trackers left for %s, reenabling all of them..." (file_best_name (as_file file));
List.iter (fun t ->
- match t.tracker_status with
- (* only re-enable after normal error *)
+ match t.tracker_status with
+ (* only re-enable after normal error *)
| Disabled _ -> t.tracker_status <- Enabled
- | _ -> ()) file.file_trackers;
+ | _ -> ()) file.file_trackers;
let enabled_trackers = List.filter (fun t -> tracker_is_enabled t) file.file_trackers in
if enabled_trackers = [] && (file_state file) <> FilePaused then
- begin
- file_pause (as_file file) (CommonUserDb.admin_user ());
- lprintf_file_nl (as_file file) "Paused %s, no usable trackers left" (file_best_name (as_file file))
- end;
+ begin
+ file_pause (as_file file) (CommonUserDb.admin_user ());
+ lprintf_file_nl (as_file file) "Paused %s, no usable trackers left" (file_best_name (as_file file))
+ end;
enabled_trackers
end in
@@ -173,12 +182,12 @@ let connect_trackers file event f =
then
begin
(* if we already tried to connect but failed, disable tracker, but allow re-enabling *)
- if file.file_tracker_connected && t.tracker_last_clients_num = 0 &&
- t.tracker_last_conn < 1 then begin
- if !verbose_msg_servers then
- lprintf_nl "Request error from tracker: disabling %s" t.tracker_url;
- t.tracker_status <- Disabled (intern "MLDonkey: Request error from tracker")
- end
+ if file.file_tracker_connected && t.tracker_last_clients_num = 0 && t.tracker_last_conn < 1 then
+ begin
+ if !verbose_msg_servers then
+ lprintf_nl "Request error from tracker: disabling %s" t.tracker_url;
+ t.tracker_status <- Disabled (intern "MLDonkey: Request error from tracker")
+ end
(* Send request to tracker *)
else begin
let args = if String.length t.tracker_id > 0 then
@@ -188,7 +197,7 @@ let connect_trackers file event f =
("key", t.tracker_key) :: args else args
in
if !verbose_msg_servers then
- lprintf_nl "get_sources_from_tracker: tracker_connected:%s id:%s key:%s last_clients:%i last_conn-last_time:%i file: %s"
+ lprintf_nl "connect_trackers: tracker_connected:%s id:%s key:%s last_clients:%i last_conn-last_time:%i file: %s"
(string_of_bool file.file_tracker_connected)
t.tracker_id t.tracker_key t.tracker_last_clients_num
(t.tracker_last_conn - last_time()) file.file_name;
@@ -354,7 +363,7 @@ let disconnect_clients file =
let download_finished file =
if List.memq file !current_files then
begin
- connect_trackers file "completed" (fun _ _ -> ()); (*must be called before swarmer gets removed from file*)
+ connect_trackers file "completed" false (fun _ _ -> ()); (*must be called before swarmer gets removed from file*)
(*CommonComplexOptions.file_completed*)
file_completed (as_file file);
(* Remove the swarmer for this file as it is not useful anymore... *)
@@ -1321,16 +1330,30 @@ let chk_keyval key n url name =
0
end
+(** Check that client is valid and record it *)
+let maybe_new_client file id ip port =
+ let cc = Geoip.get_country_code_option ip in
+ if id != Sha1.null
+ && id <> !!client_uid
+ && ip != Ip.null
+ && port <> 0
+ && (match !Ip.banned (ip, cc) with
+ | None -> true
+ | Some reason ->
+ if !verbose_connect then
+ lprintf_file_nl (as_file file) "%s:%d blocked: %s" (Ip.to_string ip) port reason;
+ false)
+ then
+ ignore (new_client file id (ip,port) cc);
+ if !verbose_sources > 1 then
+ lprintf_file_nl (as_file file) "Received %s:%d" (Ip.to_string ip) port;
+ ()
-(** In this function we initiate a connection to the file tracker
- to get sources.
+(** In this function we interact with the tracker
@param file The file for which we want some sources
- @param url Url of the tracker
- If we have less than !!ask_tracker_threshold sources
- and if we respect the file_tracker_interval then
- we really ask sources to the tracker
+ @param need_sources whether we need any sources
*)
-let get_sources_from_tracker file =
+let talk_to_tracker file need_sources =
let f t filename =
(*This is the function which will be called by the http client
for parsing the response
@@ -1350,7 +1373,7 @@ let get_sources_from_tracker file =
in
t.tracker_interval <- 600;
t.tracker_min_interval <- 600;
- t.tracker_last_clients_num <- 0;
+ if need_sources then t.tracker_last_clients_num <- 0;
match v with
Dictionary list ->
List.iter (fun (key,value) ->
@@ -1367,7 +1390,7 @@ let get_sources_from_tracker file =
match (key, value) with
| String "failure reason", String failure ->
(* On failure, disable the tracker, count the attempts and forbid re-enabling *)
- t.tracker_status <- (match t.tracker_status with
+ t.tracker_status <- (match t.tracker_status with
| Disabled_failure (i,_) -> Disabled_failure (i + 1, intern failure)
| _ -> Disabled_failure (1, intern failure));
lprintf_file_nl (as_file file) "Failure no. %d%s from Tracker %s in file: %s Reason: %s"
@@ -1413,11 +1436,10 @@ let get_sources_from_tracker file =
lprintf_file_nl (as_file file) "%s in file: %s has tracker id %s" t.tracker_url file.file_name n
| String "peers", List list ->
+ if need_sources then
List.iter (fun v ->
match v with
- Dictionary list ->
- t.tracker_last_clients_num <- t.tracker_last_clients_num + 1;
-
+ | Dictionary list ->
let peer_id = ref Sha1.null in
let peer_ip = ref Ip.null in
let port = ref 0 in
@@ -1433,25 +1455,9 @@ let get_sources_from_tracker file =
| _ -> ()
) list;
- (* Only record valid clients *)
- let cc = Geoip.get_country_code_option !peer_ip in
- if !peer_id != Sha1.null &&
- !peer_id <> !!client_uid &&
- !peer_ip != Ip.null &&
- !port <> 0 &&
- (match !Ip.banned (!peer_ip, cc) with
- None -> true
- | Some reason ->
- if !verbose_connect then
- lprintf_file_nl (as_file file) "%s:%d blocked: %s"
- (Ip.to_string !peer_ip) !port reason;
- false)
- then
- ignore (new_client file !peer_id (!peer_ip,!port) cc);
- if !verbose_sources > 1 then
- lprintf_file_nl (as_file file) "Received %s:%d"
- (Ip.to_string !peer_ip) !port;
- ()
+ t.tracker_last_clients_num <- t.tracker_last_clients_num + 1;
+ maybe_new_client file !peer_id !peer_ip !port
+
| _ -> assert false
) list
| String "peers", String p ->
@@ -1461,12 +1467,13 @@ let get_sources_from_tracker file =
get_uint8 s (pos+2),get_uint8 s (pos+3))
and port = get_int16 s (pos+4)
in
- ignore (new_client file Sha1.null (ip,port) None);
t.tracker_last_clients_num <- t.tracker_last_clients_num + 1;
+ maybe_new_client file Sha1.null ip port;
iter_comp s (pos+6) l
in
- iter_comp p 0 (String.length p)
+ if need_sources then
+ iter_comp p 0 (String.length p)
| String "private", Int n -> ()
(* TODO: if set to 1, disable peer exchange *)
@@ -1475,9 +1482,9 @@ let get_sources_from_tracker file =
(*Now, that we have added new clients to a file, it's time
to connect to them*)
if !verbose_sources > 0 then
- lprintf_file_nl (as_file file) "get_sources_from_tracker: got %i source(s) for file %s"
+ lprintf_file_nl (as_file file) "talk_to_tracker: got %i source(s) for file %s"
t.tracker_last_clients_num file.file_name;
- resume_clients file
+ if need_sources then resume_clients file
| _ -> assert false
in
@@ -1485,13 +1492,15 @@ let get_sources_from_tracker file =
if file.file_tracker_connected then ""
else "started"
in
- connect_trackers file event f
+ connect_trackers file event need_sources f
(** Check to see if file is finished, if not
try to get sources for it
*)
let recover_files () =
+ if !verbose_share then
+ lprintf_nl "recover_files";
List.iter (fun file ->
match file.file_swarmer with
None -> ()
@@ -1499,12 +1508,15 @@ let recover_files () =
(try check_finished swarmer file with e -> ());
match file_state file with
FileDownloading ->
- (try get_sources_from_tracker file with _ -> ())
+ if !verbose_share then
+ lprintf_file_nl (as_file file) "recover downloading";
+ (try talk_to_tracker file true with _ -> ())
| FileShared ->
- (try
- connect_trackers file "" (fun _ _ -> ()) with _ -> ())
+ if !verbose_share then
+ lprintf_file_nl (as_file file) "recover shared";
+ (try talk_to_tracker file false with _ -> ())
| FilePaused -> () (*when we are paused we do nothing, not even logging this vvvv*)
- | s -> lprintf_file_nl (as_file file) "Other state %s!!" (string_of_state s)
+ | s -> lprintf_file_nl (as_file file) "recover: Other state %s!!" (string_of_state s)
) !current_files
let upload_buffer = String.create 100000
@@ -1593,7 +1605,7 @@ let file_resume file =
| Enabled | Disabled_mld _ -> ()
| Disabled_failure _ | Disabled _ -> t.tracker_status <- Enabled
) file.file_trackers;
- (try get_sources_from_tracker file with _ -> ())
+ (try talk_to_tracker file true with _ -> ())
@@ -1604,7 +1616,7 @@ let file_resume file =
let file_stop file =
if file.file_tracker_connected then
begin
- connect_trackers file "stopped" (fun _ _ ->
+ connect_trackers file "stopped" false (fun _ _ ->
lprintf_file_nl (as_file file) "Tracker return: stopped %s" file.file_name;
file.file_tracker_connected <- false)
end
diff --git a/src/networks/bittorrent/bTGlobals.ml b/src/networks/bittorrent/bTGlobals.ml
index 1f23a51..f87d67b 100644
--- a/src/networks/bittorrent/bTGlobals.ml
+++ b/src/networks/bittorrent/bTGlobals.ml
@@ -235,8 +235,8 @@ let can_handle_tracker t =
let rec set_trackers file file_trackers =
match file_trackers with
- | [] -> ()
- | url :: q ->
+ | [] -> ()
+ | url :: q ->
if not (List.exists (fun tracker ->
tracker.tracker_url = url
) file.file_trackers) then
@@ -253,12 +253,12 @@ let rec set_trackers file file_trackers =
tracker_torrent_last_dl_req = 0;
tracker_id = "";
tracker_key = "";
- tracker_status = Enabled
+ tracker_status = Enabled
} in
if not (can_handle_tracker t) then
t.tracker_status <- Disabled_mld (intern "Tracker type not supported");
file.file_trackers <- t :: file.file_trackers;
- set_trackers file q
+ set_trackers file q
let new_file file_id t torrent_diskname file_temp file_state user group =
try
@@ -327,7 +327,7 @@ let new_file file_id t torrent_diskname file_temp file_state user group =
if not (Bitv.get bitmap num) then
send_client c (Have (Int64.of_int num));
check_if_interesting file c
- end
+ end
) file.file_clients
);
diff --git a/src/networks/bittorrent/bTInteractive.ml b/src/networks/bittorrent/bTInteractive.ml
index d7930e2..49bf49b 100644
--- a/src/networks/bittorrent/bTInteractive.ml
+++ b/src/networks/bittorrent/bTInteractive.ml
@@ -184,6 +184,11 @@ let op_file_print file o =
Printf.bprintf buf "\\</tr\\>\\<tr class=\\\"dl-%d\\\"\\>" (html_mods_cntr ());
html_mods_td buf [
+ ("Torrent metadata hash", "sr", "Hash");
+ ("", "sr", Sha1.to_hexa file.file_id) ];
+
+ Printf.bprintf buf "\\</tr\\>\\<tr class=\\\"dl-%d\\\"\\>" (html_mods_cntr ());
+ html_mods_td buf [
("Search for other possible Torrent Files", "sr br", "Torrent Srch");
("", "sr", Printf.sprintf "\\<a target=\\\"_blank\\\" href=\\\"http://isohunt.com/%s\\\"\\>IsoHunt\\</a\\>"
(file.file_name)
@@ -673,7 +678,7 @@ let load_torrent_string s user group =
lprintf_nl "Starting torrent download with diskname: %s"
torrent_diskname;
let file = new_download file_id torrent torrent_diskname user group in
- BTClients.get_sources_from_tracker file;
+ BTClients.talk_to_tracker file true;
CommonInteractive.start_download (file_find (file_num file));
file
@@ -688,6 +693,7 @@ let load_torrent_file filename user group =
Sys.remove filename;
ignore (load_torrent_string s user group)
+(*
let parse_tracker_reply file t filename =
(*This is the function which will be called by the http client
for parsing the response*)
@@ -723,6 +729,7 @@ for parsing the response*)
| _ -> ()
) list;
| _ -> assert false
+*)
let try_share_file torrent_diskname =
if !verbose_share then lprintf_nl "try_share_file: %s" torrent_diskname;
@@ -754,9 +761,10 @@ let try_share_file torrent_diskname =
let user = CommonUserDb.admin_user () in
let file = new_file file_id torrent torrent_diskname
filename FileShared user user.user_default_group in
- if !verbose_share then lprintf_file_nl (as_file file) "Sharing file %s" filename;
- BTClients.connect_trackers file "started"
- (parse_tracker_reply file)
+
+ if !verbose_share then
+ lprintf_file_nl (as_file file) "Sharing file %s" filename;
+ BTClients.talk_to_tracker file false
with
| Not_found ->
(* if the torrent is still there while the file is gone, remove the torrent *)
_______________________________________________
Mldonkey-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/mldonkey-users