[erlang-questions] IPv6

Per Hedeland <>
Thu Apr 2 10:55:50 CEST 2009


Raimo Niskanen <> wrote:
>
>On Fri, Mar 27, 2009 at 05:22:25PM +0100, Per Hedeland wrote:
>> Hi,
>> 
>> Is there some good reason for gen_tcp/gen_udp not auto-recognizing an
>
>Not really. But as you see for gen_tcp:connect below, the inet6
>option is currently required there even for an IPv6 address tuple.
>These are corners we have not smoothed yet.

Thanks, that's good enough for me - I was mainly contemplating whether I
should (again) modify the OTP code or sprinkle 'size(Addr) == 8' guards
over our own (and the "old" ssh, which doesn't seem to honour an 'inet6'
option) - I'll go for the former then.

>It can be argued that the tuple size alone is not
>sufficient to determine the address class. After all
>a 4-tuple can be interpreted as a IPv4-compatible
>IPv6 address if you really want.

Good point I guess - so, 4-tuple + 'inet' or no option would mean IPv4
(as today), 4-tuple + 'inet6' could mean v4-in-v6, and you could even
have 8-tuple + 'inet' set up a tunnel if you want:-) - I'm really only
interested in the 8-tuple + no option case, which I think is just plain
broken today.

For Your Inspiration:-), below is a modified version of the patches I
sent earlier, which now fix only this case, and in addition don't
override a user-set inet_db module (for "all" the people that use that
feature:-) (actually I thought about using it to fix my problem, but
since it would mean having to use a bunch of undocumented prim_inet
functions, it's really the worst option).

Thanks!
--Per

---------------

--- otp_src_R13A/lib/kernel/src/gen_tcp.erl.ORIG	2009-03-12 13:19:00.000000000 +0100
+++ otp_src_R13A/lib/kernel/src/gen_tcp.erl	2009-04-02 10:03:34.000000000 +0200
@@ -46,7 +46,7 @@
     end.
 
 connect1(Address,Port,Opts,Timer) ->
-    Mod = mod(Opts),
+    Mod = mod(Opts, Address),
     case Mod:getaddrs(Address,Timer) of
 	{ok,IPs} ->
 	    case Mod:getserv(Port) of
@@ -73,7 +73,7 @@
 %% Listen on a tcp port
 %%
 listen(Port, Opts) ->
-    Mod = mod(Opts),
+    Mod = mod(Opts, undefined),
     case Mod:getserv(Port) of
 	{ok,TP} ->
 	    Mod:listen(TP, Opts);
@@ -173,20 +173,28 @@
 %% Create a port/socket from a file descriptor 
 %%
 fdopen(Fd, Opts) ->
-    Mod = mod(Opts),
+    Mod = mod(Opts, undefined),
     Mod:fdopen(Fd, Opts).
 
-%% Get the tcp_module
-mod() -> inet_db:tcp_module().
+%% Get the tcp_module, but IPv6 address overrides default IPv4
+mod(Address) ->
+    case inet_db:tcp_module() of
+        inet_tcp when is_tuple(Address), size(Address) =:= 8 ->
+            inet6_tcp;
+        Mod ->
+            Mod
+    end.
 
 %% Get the tcp_module, but option tcp_module|inet|inet6 overrides
-mod([{tcp_module,Mod}|_]) ->
+mod([{tcp_module,Mod}|_], _Address) ->
     Mod;
-mod([inet|_]) ->
+mod([inet|_], _Address) ->
     inet_tcp;
-mod([inet6|_]) ->
+mod([inet6|_], _Address) ->
     inet6_tcp;
-mod([_|Opts]) ->
-    mod(Opts);
-mod([]) ->
-    mod().
+mod([{ip, Address}|Opts], undefined) ->
+    mod(Opts, Address);
+mod([_|Opts], Address) ->
+    mod(Opts, Address);
+mod([], Address) ->
+    mod(Address).
--- otp_src_R13A/lib/kernel/src/gen_udp.erl.ORIG	2009-03-12 13:19:00.000000000 +0100
+++ otp_src_R13A/lib/kernel/src/gen_udp.erl	2009-04-02 10:03:37.000000000 +0200
@@ -29,7 +29,7 @@
     open(Port, []).
 
 open(Port, Opts) ->
-    Mod = mod(Opts),
+    Mod = mod(Opts, undefined),
     {ok,UP} = Mod:getserv(Port),
     Mod:open(UP, Opts).
 
@@ -97,21 +97,29 @@
 %% Create a port/socket from a file descriptor 
 %%
 fdopen(Fd, Opts) ->
-    Mod = mod(),
+    Mod = mod(Opts, undefined),
     Mod:fdopen(Fd, Opts).
 
 
-%% Get the udp_module
-mod() -> inet_db:udp_module().
+%% Get the udp_module, but IPv6 address overrides default IPv4
+mod(Address) ->
+    case inet_db:udp_module() of
+        inet_udp when is_tuple(Address), size(Address) =:= 8 ->
+            inet6_udp;
+        Mod ->
+            Mod
+    end.
 
-%% Get the udp_module, but option udp_module|inet|inet6 overrides
-mod([{udp_module,Mod}|_]) ->
+%% Get the udp_module, but option tcp_module|inet|inet6 overrides
+mod([{udp_module,Mod}|_], _Address) ->
     Mod;
-mod([inet|_]) ->
+mod([inet|_], _Address) ->
     inet_udp;
-mod([inet6|_]) ->
+mod([inet6|_], _Address) ->
     inet6_udp;
-mod([_|Opts]) ->
-    mod(Opts);
-mod([]) ->
-    mod().
+mod([{ip, Address}|Opts], undefined) ->
+    mod(Opts, Address);
+mod([_|Opts], Address) ->
+    mod(Opts, Address);
+mod([], Address) ->
+    mod(Address).



More information about the erlang-questions mailing list