From 56f6acd0bed16611dee6e4a7c7a9335f5a041dbe Mon Sep 17 00:00:00 2001 From: ygrek Date: Mon, 10 May 2010 15:04:09 +0300 Subject: [PATCH] discover self IP via DC UserIP --- src/networks/direct_connect/dcInteractive.ml | 3 +- src/networks/direct_connect/dcProtocol.ml | 41 ++++++++++++------------ src/networks/direct_connect/dcServers.ml | 48 +++++++++++++++------------- src/utils/cdk/list2.ml | 4 +++ src/utils/cdk/list2.mli | 6 +++- 5 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/networks/direct_connect/dcInteractive.ml b/src/networks/direct_connect/dcInteractive.ml index be595155..dce721bd 100644 --- a/src/networks/direct_connect/dcInteractive.ml +++ b/src/networks/direct_connect/dcInteractive.ml @@ -92,7 +92,6 @@ let start_result_download r = let exn_catch f x = try `Ok (f x) with exn -> `Exn exn let opt_default default = function None -> default | Some v -> v -let filter_map f l = List.fold_left (fun acc x -> match f x with Some y -> y :: acc | None -> acc) [] l let parse_url url user group = match exn_catch parse_magnet_url url with @@ -101,7 +100,7 @@ let parse_url url user group = if !verbose then lprintf_nl "Got magnet url %S" url; (* TODO multiple TTHs, multiple xt, automatic merge of downloads from different networks (?!) *) - match filter_map (function TigerTree tth -> Some tth | _ -> None) magnet#uids with + match List2.filter_map (function TigerTree tth -> Some tth | _ -> None) magnet#uids with | [] -> "No TTH found in magnet url", false | tth::_ -> let _ = start_new_download None (TigerTree.to_string tth) "" magnet#name (opt_default 0L magnet#size) in diff --git a/src/networks/direct_connect/dcProtocol.ml b/src/networks/direct_connect/dcProtocol.ml index 10c9b08b..539a9386 100644 --- a/src/networks/direct_connect/dcProtocol.ml +++ b/src/networks/direct_connect/dcProtocol.ml @@ -133,11 +133,11 @@ module SimpleNickList = functor (M: sig val cmd : string end) -> struct let list = String2.split_simplify t '$' in let list = List.rev_map (fun nick -> dc_to_utf nick) list in list - let print t = + let print t = lprintf "%s list ( " M.cmd; List.iter (fun s -> lprintf "%s " s) t; lprintf_nl " )" - let write buf t = + let write buf t = Buffer.add_char buf ' '; List.iter (fun nick -> Printf.bprintf buf "%s %s$$" M.cmd (utf_to_dc nick)) t end @@ -926,27 +926,28 @@ module UGetBlock = struct Printf.bprintf buf "$Get %Ld$ %Ld %s" t.upos t.ubytes t.ufilename; (*UTF8*) if !verbose_msg_clients then lprintf_nl "Sending: (%s)" (Buffer.contents buf) end - -module UserIP = struct (* TODO *) + +module UserIP = struct type t = string list - let parse s = String2.split_simplify s '$' + + let parse s = String2.split_simplify s '$' + + let parse_nameip = + List2.filter_map (fun s -> + match String2.split s ' ' with + | [name;addr] -> Some (dc_to_utf name, Ip.addr_of_string addr) + | _ -> None) + let print st = - lprintf "UserIP list ("; - List.iter (fun s -> lprintf "%s " s) st; - lprintf_nl " )" - let write buf st = - lprintf_nl "UserIP:"; - Buffer.add_char buf ' '; - let rec iter s = - ( match s with - | [] -> lprintf_nl "UserIP: ()" - | hd :: [] -> lprintf_nl "UserIP: hd :: [] hd=%s" hd; Buffer.add_string buf hd - | hd :: tl -> lprintf_nl "UserIP: hd :: tl hd=%s" hd; Printf.bprintf buf "%s$$" hd; iter tl ) - in - iter st + lprintf "UserIP list ("; + List.iter (fun s -> lprintf "%s " (dc_to_utf s)) st; + lprintf_nl ")" + + let write buf st = + Printf.bprintf buf "$UserIP %s" (String.concat "$$" (List.map utf_to_dc st)) end -(* Message type definitions and basic parsing *) +(* Message type definitions and basic parsing *) type t = | AdcGetReq of AdcGet.t | AdcSndReq of AdcSnd.t @@ -1100,7 +1101,7 @@ let dc_write buf m = | UnknownReq t -> Buffer.add_string buf t | UGetBlockReq t -> UGetBlock.write buf t | UserCommandReq -> () - | UserIPReq t -> Buffer.add_string buf "$UserIP"; UserIP.write buf t + | UserIPReq t -> UserIP.write buf t | ValidateNickReq s -> Printf.bprintf buf "$ValidateNick %s" s | ValidateDenideReq s -> Buffer.add_string buf s | VersionReq s -> Printf.bprintf buf "$Version %s" s ) diff --git a/src/networks/direct_connect/dcServers.ml b/src/networks/direct_connect/dcServers.ml index 526f706f..8c485b32 100644 --- a/src/networks/direct_connect/dcServers.ml +++ b/src/networks/direct_connect/dcServers.ml @@ -391,7 +391,7 @@ let client_to_server s m sock = if !verbose_unknown_messages then lprintf_nl "Codedname was wrong in Search receiving"; raise Not_found ) in - let message = (* message structure for both active and passive messages *) + let message = (* message structure for both active and passive messages *) let module S = SR in { S.owner = s.server_last_nick; S.directory = directory; @@ -413,11 +413,11 @@ let client_to_server s m sock = end; if t.Search.passive then dc_send_msg sock (SRReq ( message )) - else + else DcClients.udp_send (Ip.of_string t.Search.ip) (int_of_string t.Search.port) (SRReq ( message )) ) files in - + if t.Search.passive then begin (* if passive search received *) if not !!firewalled then begin (* and we are in active mode *) if (t.Search.nick <> s.server_last_nick) then begin (* if search is not from ourself ... *) @@ -448,7 +448,7 @@ let client_to_server s m sock = let u = new_user (Some s) t.To.from in u.user_messages <- u.user_messages @ [ (int_of_float (current_time ()), t.To.from, PrivateMessage (0, t.To.message))]; - + | UnknownReq m -> if m <> "" then if !verbose_unexpected_messages || !verbose_msg_servers then @@ -458,34 +458,38 @@ let client_to_server s m sock = else lprintf_nl "%s (%s)" txt m | UserCommandReq -> () (* Not supported atm *) - + | UserIPReq st -> (* CHECK *) if !verbose_msg_servers then lprintf_nl "Received $UserIP"; - List.iter ( fun nameip -> - lprintf_nl "UserIPReq: nameip=%s" nameip; - match String2.split nameip ' ' with - | name :: ip :: [] -> - (try - let u = search_user_by_name name in - ( try u.user_ip <- Ip.addr_of_string ip with _ -> () ); - lprintf_nl "Added ip %s to user %s" (Ip.string_of_addr u.user_ip) u.user_nick - with _ -> - if !verbose_unexpected_messages then lprintf_nl "No user by name %s" name ) - | _ -> () - ) st; - - | ValidateDenideReq n -> + let st = UserIP.parse_nameip st in + List.iter begin fun (name,addr) -> + lprintf_nl "UserIP: %s %s" name (Ip.string_of_addr addr); + try + if name = s.server_last_nick then + begin + match addr with + | Ip.AddrIp ip -> lprintf_nl "Received self IP: %s" (Ip.to_string ip); last_high_id := ip + | Ip.AddrName _ -> () + end; + let u = search_user_by_name name in + u.user_ip <- addr; + lprintf_nl "Added ip %s to user %s" (Ip.string_of_addr u.user_ip) u.user_nick + with _ -> + if !verbose_unexpected_messages then lprintf_nl "No user by name %s" name + end st + + | ValidateDenideReq n -> let errortxt = Printf.sprintf "Nick %s is already in use" n in if !verbose_unexpected_messages || !verbose_msg_servers then lprintf_nl "%s" errortxt; disconnect_server s (Closed_for_error errortxt ) - + | VersionReq v -> () - + | _ -> lprintf_nl "--> Unhandled server message. Implement ?:"; DcProtocol.dc_print m ) - + (* connect to DC server *) let connect_server s = if can_open_connection connection_manager then diff --git a/src/utils/cdk/list2.ml b/src/utils/cdk/list2.ml index d8642fc1..0dc7a92e 100644 --- a/src/utils/cdk/list2.ml +++ b/src/utils/cdk/list2.ml @@ -116,3 +116,7 @@ let shuffle list = a.(p) <- tmp; done; Array.to_list a + +let filter_map f = + List.fold_left (fun acc x -> match f x with Some y -> y :: acc | None -> acc) [] + diff --git a/src/utils/cdk/list2.mli b/src/utils/cdk/list2.mli index 4a9646e5..3f99a2a0 100644 --- a/src/utils/cdk/list2.mli +++ b/src/utils/cdk/list2.mli @@ -44,4 +44,8 @@ val safe_iter : ('a -> unit) -> 'a list -> unit val min : 'a list -> 'a val max : 'a list -> 'a -val shuffle: 'a list -> 'a list \ No newline at end of file +val shuffle: 'a list -> 'a list + +(** [filter_map f l] *) +val filter_map : ('a -> 'b option) -> 'a list -> 'b list + -- 2.11.4.GIT