From edd68265535253e390cc86a3aad0d53f1a785d09 Mon Sep 17 00:00:00 2001
From: ygrek <ygrek@autistici.org>
Date: Sun, 1 Sep 2013 23:07:17 +0800
Subject: [PATCH] BT: disable announcing to 127.0.0.1 (bug #36886)

---
 src/networks/bittorrent/bTClients.ml |   10 +++++++---
 src/utils/net/http_client.ml         |   10 ++++++++--
 src/utils/net/http_client.mli        |    6 +++++-
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/networks/bittorrent/bTClients.ml b/src/networks/bittorrent/bTClients.ml
index 2d0dbe2..01ddd52 100644
--- a/src/networks/bittorrent/bTClients.ml
+++ b/src/networks/bittorrent/bTClients.ml
@@ -200,8 +200,11 @@ let talk_to_udp_tracker host port args file t need_sources =
     if !verbose_msg_servers then
       lprintf_nl "udpt start with %s:%d" host port;
     Ip.async_ip host (fun ip ->
-(*       lprintf_nl "udpt resolved %s to ip %s" host (Ip.to_string ip); *)
-      try interact ip with exn -> lprintf_nl "udpt interact exn %s" (Printexc2.to_string exn))
+(*         lprintf_nl "udpt resolved %s to ip %s" host (Ip.to_string ip); *)
+        if not (Ip.equal Ip.localhost ip) then
+          try interact ip with exn -> lprintf_nl "udpt interact exn %s" (Printexc2.to_string exn)
+        else if !verbose_msg_servers then
+          lprintf_nl "udpt ignoring tracker %s (resolves to localhost)" host)
       (fun () -> 
         if !verbose_msg_servers then
           lprintf_nl "udpt failed to resolve %s" host)
@@ -339,11 +342,12 @@ let connect_trackers file event need_sources f =
               let module H = Http_client in
               let r = {
                   H.basic_request with
-                  H.req_url = Url.of_string ~args: args url;
+                  H.req_url = Url.of_string ~args url;
                   H.req_proxy = !CommonOptions.http_proxy;
                   H.req_user_agent = get_user_agent ();
                   (* #4541 [egs]  supports redirect *)
                   H.req_max_retry = !!max_tracker_redirect;
+                  H.req_filter_ip = (fun ip -> not (Ip.equal Ip.localhost ip));
                 } in
 
               if !verbose_msg_servers then
diff --git a/src/utils/net/http_client.ml b/src/utils/net/http_client.ml
index 22a4f2c..49ef1aa 100644
--- a/src/utils/net/http_client.ml
+++ b/src/utils/net/http_client.ml
@@ -38,12 +38,13 @@ type http_request =
 | DELETE
 | TRACE
 
-type error = [ `HTTP of int | `RST of BasicSocket.close_reason | `DNS ]
+type error = [ `HTTP of int | `RST of BasicSocket.close_reason | `DNS | `Block of Ip.t ]
 
 let show_error = function
 | `HTTP code -> Printf.sprintf "HTTP error code %d" code
 | `RST reason -> Printf.sprintf "Connection closed : %s" (BasicSocket.string_of_reason reason)
 | `DNS -> Printf.sprintf "DNS resolution failed"
+| `Block ip -> Printf.sprintf "Blocked connection to %s" (Ip.to_string ip)
 
 let verbose = ref false
 
@@ -61,6 +62,7 @@ type request = {
     req_max_retry : int;
     req_save : bool;
     req_max_total_time : float;
+    req_filter_ip : (Ip.t -> bool);
   }
 
 type content_handler = 
@@ -85,8 +87,9 @@ let basic_request = {
     req_max_retry = 0;
     req_save = false;
     req_max_total_time = infinite_timeout;
+    req_filter_ip = (fun _ -> true);
   }
-      
+
 let make_full_request r =
   let url = r.req_url in
   let args = url.args in
@@ -245,6 +248,9 @@ let rec get_page r content_handler f ferr =
     in
 (*    lprintf "async_ip ...\n"; *)
     Ip.async_ip server (fun ip ->
+        match r.req_filter_ip ip with
+        | false -> ferr (`Block ip)
+        | true ->
 (*         lprintf "IP done %s:%d\n" (Ip.to_string ip) port;*)
         let token = create_token unlimited_connection_manager in
         let sock = TcpBufferedSocket.connect token "http client connecting"
diff --git a/src/utils/net/http_client.mli b/src/utils/net/http_client.mli
index 2f484f5..a8edfb6 100644
--- a/src/utils/net/http_client.mli
+++ b/src/utils/net/http_client.mli
@@ -47,6 +47,10 @@ type request = {
     req_save : bool;
     (** maximum time whole request processing is allowed to take, in seconds *)
     req_max_total_time : float;
+    (** this function is called after DNS resolution,
+        returning [false] will block connection to the given ip
+        and HTTP request will fail with `Block error *)
+    req_filter_ip : (Ip.t -> bool);
   }
 
 type content_handler = 
@@ -55,7 +59,7 @@ type content_handler =
 val basic_request : request
 
 (** either HTTP error code or low-level network error or DNS *)
-type error = [ `HTTP of int | `RST of BasicSocket.close_reason | `DNS ]
+type error = [ `HTTP of int | `RST of BasicSocket.close_reason | `DNS | `Block of Ip.t ]
 val show_error : error -> string
 
 val get_page : request -> content_handler -> (unit -> unit) -> (error -> unit) -> unit
-- 
1.7.6.6.GIT

