[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Sks-devel] Patch (partial): IPv6 support (in progress)
From: |
Kim Minh Kaplan |
Subject: |
Re: [Sks-devel] Patch (partial): IPv6 support (in progress) |
Date: |
Mon, 02 Mar 2009 12:55:21 +0000 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) |
Phil Pennock:
> Can those with more experience in OCaml please take a look over this and
> tell me if I'm heading down the right path?
>
> This patch theoretically adds support for IPv6 in recon; it adds the
> settings hooks for hkp too, but doesn't add anything that uses that yet.
> It should both listen on IPv6 and connect outbound too.
>
> It compiles. It runs. I see both listening sockets with lsof. It
> doesn't do anything soon enough for me to see tonight how well I've
> done, as I need to go get some sleep. I'm not sufficiently comfortable
> to leave sks-peer.spodhuis.org running this code overnight, so I've
> reverted to 1.1.0.
>
> It's my first OCaml hacking and my style sucks and I spend more time
> debugging to get it to compile than I care to think about.
>
> A critical eye and constructive comments appreciated.
>
> Oh, and I've no idea how recent support for IPv6 in OCaml is and have
> made no effort to gracefully degrade to either old OCaml environments or
> systems without IPv6 support. First, I want to get it working for
> anyone, *then* I can worry about making it conditional.
Hello,
it is funny that you send this as I was just doing something very
similar this weekend. Here is what I did. I am still experimenting
with what actually works, what does not and trying to find what I broke.
I'll have a look at the way you did it when I have some time, probably
wednesday.
Kim Minh.
--- a/eventloop.ml Fri May 23 21:16:40 2008 -0400
+++ b/eventloop.ml Mon Mar 02 12:48:35 2009 +0000
@@ -121,10 +121,7 @@
let create_sock addr =
try
- let domain =
- match addr with
- ADDR_UNIX _ -> PF_UNIX
- | ADDR_INET (_,_) -> PF_INET in
+ let domain = domain_of_sockaddr addr in
let sock =
socket ~domain ~kind:SOCK_STREAM ~protocol:0 in
setsockopt sock SO_REUSEADDR true;
diff -r e30dc5376cbb membership.ml
--- a/membership.ml Fri May 23 21:16:40 2008 -0400
+++ b/membership.ml Mon Mar 02 12:48:35 2009 +0000
@@ -34,32 +34,34 @@
let whitespace = Str.regexp "[ \t]+"
-let lookup_hostname string =
- try (Unix.gethostbyname string).Unix.h_addr_list.(0)
- with
- | Invalid_argument _ | Not_found -> raise (Lookup_failure string)
+let lookup_hostname string port =
+ let addrs = Unix.getaddrinfo string port [Unix.AI_SOCKTYPE(Unix.SOCK_STREAM)]
+ in
+ if List.length addrs = 0 then raise (Lookup_failure string);
+ addrs
let local_recon_addr () =
- Unix.ADDR_INET (lookup_hostname !Settings.hostname, recon_port)
+ lookup_hostname !Settings.hostname (string_of_int recon_port)
let local_recon_addr = Utils.unit_memoize local_recon_addr
let remove_self addresses =
- List.filter ~f:(fun (addr,str) -> addr <> local_recon_addr ()) addresses
+ List.filter ~f:(fun (addr, str) -> List.mem addr (local_recon_addr()))
+ addresses
let convert_address l =
- try
- sscanf l "%s %d"
- (fun addr port -> Unix.ADDR_INET (lookup_hostname addr,port))
- with
+ try
+ sscanf l "%s %s" lookup_hostname
+ with
Scanf.Scan_failure _ | End_of_file | Failure _ -> raise (Malformed_entry l)
let load_membership_file file =
let rec loop list =
try
let line = decomment (input_line file) in
- let addr = convert_address line in
- (addr,line) :: loop list
+ let addrs = convert_address line in
+ let pairs = List.map (fun addr -> (addr,line)) addrs in
+ pairs @ loop list
with
| End_of_file -> list
| Lookup_failure addr ->
@@ -101,7 +103,7 @@
let membership_string () =
let (mshp,_) = !membership in
let to_string (addr,str) =
- sprintf "%s(%s)" (sockaddr_to_string addr) str
+ sprintf "%s(%s)" (sockaddr_to_string addr.Unix.ai_addr) str
in
let strings = List.map ~f:to_string (Array.to_list mshp) in
"Membership: " ^ String.concat ~sep:", " strings
@@ -149,7 +151,14 @@
let same_inet_addr addr1 addr2 =
match (addr1,addr2) with
- (Unix.ADDR_INET (ip1,_), Unix.ADDR_INET (ip2,_)) -> ip1 = ip2
+ (Unix.ADDR_INET (ip1,_), Unix.ADDR_INET (ip2,_)) ->
+ let ipv6_addr addr =
+ let addr_str = Unix.string_of_inet_addr addr in
+ if String.contains addr_str ':'
+ then addr_str
+ else "::ffff:" ^ addr_str
+ in
+ ipv6_addr(ip1) = ipv6_addr(ip2)
| _ -> false
let test addr =
@@ -159,7 +168,7 @@
let found = ref false in
let i = ref 0 in
while !i < Array.length m && not !found do
- if same_inet_addr addr (fst m.(!i)) then
+ if same_inet_addr addr (fst m.(!i)).Unix.ai_addr then
found := true;
incr i
done;
diff -r e30dc5376cbb reconCS.ml
--- a/reconCS.ml Fri May 23 21:16:40 2008 -0400
+++ b/reconCS.ml Mon Mar 02 12:48:35 2009 +0000
@@ -132,21 +132,21 @@
let connect tree ~filters ~partner ~self =
(* TODO: change the following to depend on the address type *)
let s = Unix.socket
- ~domain:Unix.PF_INET
- ~kind:Unix.SOCK_STREAM
- ~protocol:0
+ ~domain:partner.Unix.ai_family
+ ~kind:partner.Unix.ai_socktype
+ ~protocol:partner.Unix.ai_protocol
in
let run () =
Unix.bind s ~addr:(get_client_recon_addr ());
- Unix.connect s ~addr:partner;
+ Unix.connect s ~addr:partner.Unix.ai_addr;
let cin = Channel.sys_in_from_fd s
and cout = Channel.sys_out_from_fd s in
plerror 4 "Initiating reconciliation";
- let remote_config = handle_config cin cout filters partner in
+ let remote_config = handle_config cin cout filters partner.Unix.ai_addr in
ignore (Unix.alarm !Settings.reconciliation_timeout);
let http_port = config_get_http_port remote_config in
- let remote_http_address = change_port partner http_port in
+ let remote_http_address = change_port partner.Unix.ai_addr http_port in
let data = Server.handle tree cin cout in
(data,remote_http_address)
diff -r e30dc5376cbb reconComm.ml
--- a/reconComm.ml Fri May 23 21:16:40 2008 -0400
+++ b/reconComm.ml Mon Mar 02 12:48:35 2009 +0000
@@ -65,13 +65,42 @@
with
Not_found -> false
+(** Get the protocol family needed for the use of an address *)
+let get_addr_pf addr =
+ match addr with
+ Unix.ADDR_INET(ip, _) ->
+ if String.contains (Unix.string_of_inet_addr ip) ':'
+ then Unix.PF_INET6
+ else Unix.PF_INET
+ | Unix.ADDR_UNIX(_) -> Unix.PF_UNIX
+
+(** Given two protocol families, guess a minimal compatible family *)
+let get_compat_pf addr1 addr2 =
+ match (get_addr_pf addr1, get_addr_pf addr2) with
+ (Unix.PF_INET6, _) | (_, Unix.PF_INET6) -> Unix.PF_INET6
+ | (pf, _) -> pf
+
+(** Map an IP address to IPv6 if protocol family is PF_INET6 *)
+let map_addr pf addr =
+ match (pf, addr) with
+ (Unix.PF_INET6, Unix.ADDR_INET(ip, port)) ->
+ let addr_str = Unix.string_of_inet_addr ip in
+ if String.contains addr_str ':'
+ then addr
+ else Unix.ADDR_INET(Unix.inet_addr_of_string ("::ffff:" ^ addr_str),
port)
+ | _ -> addr
+
let get_keystrings_via_http addr hashes =
+ let recon_addr = get_client_recon_addr() in
+ let pf = get_compat_pf addr recon_addr in
+ let addr = map_addr pf addr in
+ let recon_addr = map_addr pf recon_addr in
let s = Unix.socket
- ~domain:Unix.PF_INET
+ ~domain:pf
~kind:Unix.SOCK_STREAM
~protocol:0 in
protect ~f:(fun () ->
- Unix.bind s ~addr:(get_client_recon_addr ());
+ Unix.bind s ~addr:recon_addr;
Unix.connect s ~addr;
let cin = Channel.sys_in_from_fd s
and cout = Channel.sys_out_from_fd s in
diff -r e30dc5376cbb reconserver.ml
--- a/reconserver.ml Fri May 23 21:16:40 2008 -0400
+++ b/reconserver.ml Mon Mar 02 12:48:35 2009 +0000
@@ -211,7 +211,7 @@
else
begin
let partner = choose_partner () in
- plerror 4 "Recon partner: %s" (sockaddr_to_string partner);
+ plerror 4 "Recon partner: %s" (sockaddr_to_string partner.Unix.ai_addr);
let filters = get_filters () in
let (results,http_addr) =
ReconCS.connect (get_ptree ()) ~filters ~partner
Re: [Sks-devel] [PATCH] IPv6 support, Kim Minh Kaplan, 2009/03/07