diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kernel/src/gen_sctp.erl | 30 | ||||
-rw-r--r-- | lib/kernel/src/gen_tcp.erl | 36 | ||||
-rw-r--r-- | lib/kernel/src/gen_udp.erl | 34 | ||||
-rw-r--r-- | lib/kernel/test/gen_sctp_SUITE.erl | 59 | ||||
-rw-r--r-- | lib/kernel/test/gen_tcp_api_SUITE.erl | 57 | ||||
-rw-r--r-- | lib/kernel/test/gen_udp_SUITE.erl | 60 |
6 files changed, 233 insertions, 43 deletions
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index a1542ab507..cccfa75005 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -39,7 +39,7 @@ open() -> open([]). open(Opts) when is_list(Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), case Mod:open(Opts) of {error,badarg} -> erlang:error(badarg, [Opts]); @@ -234,17 +234,27 @@ controlling_process(S, Pid) -> %% Utilites %% -%% Get the SCTP moudule -mod() -> inet_db:sctp_module(). +%% Get the SCTP module, but IPv6 address overrides default IPv4 +mod(Address) -> + case inet_db:sctp_module() of + inet_sctp when tuple_size(Address) =:= 8 -> + inet6_sctp; + Mod -> + Mod + end. %% Get the SCTP module, but option sctp_module|inet|inet6 overrides -mod([{sctp_module,Mod}|_]) -> +mod([{sctp_module,Mod}|_], _Address) -> Mod; -mod([inet|_]) -> +mod([inet|_], _Address) -> inet_sctp; -mod([inet6|_]) -> +mod([inet6|_], _Address) -> inet6_sctp; -mod([_|Opts]) -> - mod(Opts); -mod([]) -> - mod(). +mod([{ip, Address}|Opts], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 7401b06a64..16a87d71b6 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -46,7 +46,7 @@ connect(Address, Port, Opts, Time) -> 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 @@ try_connect([], _Port, _Opts, _Timer, _Mod, Err) -> %% 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,30 @@ controlling_process(S, NewOwner) -> %% 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 tuple_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], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 6bded4bda6..99020c7b6c 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -29,7 +29,7 @@ open(Port) -> open(Port, []). open(Port, Opts) -> - Mod = mod(Opts), + Mod = mod(Opts, undefined), {ok,UP} = Mod:getserv(Port), Mod:open(UP, Opts). @@ -97,21 +97,31 @@ controlling_process(S, NewOwner) -> %% 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 tuple_size(Address) =:= 8 -> + inet6_udp; + Mod -> + Mod + end. %% Get the udp_module, but option udp_module|inet|inet6 overrides -mod([{udp_module,Mod}|_]) -> +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], _) -> + mod(Opts, Address); +mod([{ifaddr, Address}|Opts], _) -> + mod(Opts, Address); +mod([_|Opts], Address) -> + mod(Opts, Address); +mod([], Address) -> + mod(Address). diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index eb06d4324b..9aa94a0868 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -27,12 +27,12 @@ -export( [basic/1, api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1, - xfer_min/1,xfer_active/1,def_sndrcvinfo/1]). + xfer_min/1,xfer_active/1,def_sndrcvinfo/1,implicit_inet6/1]). all(suite) -> [basic, api_open_close,api_listen,api_connect_init,api_opts, - xfer_min,xfer_active,def_sndrcvinfo]. + xfer_min,xfer_active,def_sndrcvinfo,implicit_inet6]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(15)), @@ -551,3 +551,58 @@ api_opts(Config) when is_list(Config) -> {{error,einval},{unix,sunos}} -> ok end. + +implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line + case gen_sctp:open(0, [inet6]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Loopback), + ?line ok = gen_sctp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = + ok(gen_sctp:open(0, [{ip,Localhost}])), + ?line implicit_inet6(S2, Localhost), + ?line ok = gen_sctp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = + ok(gen_sctp:open(0, [{ifaddr,Host}])), + ?line implicit_inet6(S3, Host), + ?line ok = gen_sctp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_sctp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S1, Addr) -> + ?line ok = gen_sctp:listen(S1, true), + ?line P1 = ok(inet:port(S1)), + ?line S2 = ok(gen_sctp:open(0, [inet6])), + ?line P2 = ok(inet:port(S2)), + ?line #sctp_assoc_change{state=comm_up} = + ok(gen_sctp:connect(S2, Addr, P1, [])), + ?line case ok(gen_sctp:recv(S1)) of + {Addr,P2,[],#sctp_assoc_change{state=comm_up}} -> + ok + end, + ?line case ok(inet:sockname(S1)) of + {Addr,P1} -> ok; + {{0,0,0,0,0,0,0,0},P1} -> ok + end, + ?line case ok(inet:sockname(S2)) of + {Addr,P2} -> ok; + {{0,0,0,0,0,0,0,0},P2} -> ok + end, + ?line ok = gen_sctp:close(S2). diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl index 11d19aaa82..94637290a1 100644 --- a/lib/kernel/test/gen_tcp_api_SUITE.erl +++ b/lib/kernel/test/gen_tcp_api_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -30,10 +30,11 @@ t_connect/1, t_connect_bad/1, t_recv/1, t_recv_timeout/1, t_recv_eof/1, t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1, - t_fdopen/1]). + t_fdopen/1, t_implicit_inet6/1]). all(suite) -> [t_accept, t_connect, t_recv, t_shutdown_write, - t_shutdown_both, t_shutdown_error, t_fdopen]. + t_shutdown_both, t_shutdown_error, t_fdopen, + t_implicit_inet6]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -156,6 +157,54 @@ t_fdopen(Config) when is_list(Config) -> ok. +%%% implicit inet6 option to api functions + +t_implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line + case gen_tcp:listen(0, [inet6]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Loopback), + ?line ok = gen_tcp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = ok(gen_tcp:listen(0, [{ip,Localhost}])), + ?line implicit_inet6(S2, Localhost), + ?line ok = gen_tcp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = ok(gen_tcp:listen(0, [{ifaddr,Host}])), + ?line implicit_inet6(S3, Host), + ?line ok = gen_tcp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_tcp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S, Addr) -> + ?line P = ok(inet:port(S)), + ?line S2 = ok(gen_tcp:connect(Addr, P, [])), + ?line P2 = ok(inet:port(S2)), + ?line S1 = ok(gen_tcp:accept(S)), + ?line P1 = P = ok(inet:port(S1)), + ?line {Addr,P2} = ok(inet:peername(S1)), + ?line {Addr,P1} = ok(inet:peername(S2)), + ?line {Addr,P1} = ok(inet:sockname(S1)), + ?line {Addr,P2} = ok(inet:sockname(S2)), + ?line ok = gen_tcp:close(S2), + ?line ok = gen_tcp:close(S1). + + %%% Utilities @@ -217,3 +266,5 @@ unused_ip(A, B, C, D) -> {ok, _} -> unused_ip(A, B, C, D+1); {error, _} -> {ok, {A, B, C, D}} end. + +ok({ok,V}) -> V. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index fa1991872b..44dd8607b9 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -34,12 +34,12 @@ -export([send_to_closed/1, buffer_size/1, binary_passive_recv/1, bad_address/1, - read_packets/1, open_fd/1, connect/1]). + read_packets/1, open_fd/1, connect/1, implicit_inet6/1]). all(suite) -> [send_to_closed, buffer_size, binary_passive_recv, bad_address, read_packets, - open_fd, connect]. + open_fd, connect, implicit_inet6]. init_per_testcase(_Case, Config) -> ?line Dog=test_server:timetrap(?default_timeout), @@ -425,3 +425,57 @@ connect(Config) when is_list(Config) -> ok = gen_udp:send(S2, <<16#deadbeef:32>>), {error,econnrefused} = gen_udp:recv(S2, 0, 5), ok. + +implicit_inet6(Config) when is_list(Config) -> + ?line Hostname = ok(inet:gethostname()), + ?line Active = {active,false}, + ?line + case gen_udp:open(0, [inet6,Active]) of + {ok,S1} -> + ?line + case inet:getaddr(Hostname, inet6) of + {ok,Host} -> + ?line Loopback = {0,0,0,0,0,0,0,1}, + ?line io:format("~s ~p~n", ["Loopback",Loopback]), + ?line implicit_inet6(S1, Active, Loopback), + ?line ok = gen_udp:close(S1), + %% + ?line Localhost = + ok(inet:getaddr("localhost", inet6)), + ?line io:format("~s ~p~n", ["localhost",Localhost]), + ?line S2 = + ok(gen_udp:open(0, [{ip,Localhost},Active])), + ?line implicit_inet6(S2, Active, Localhost), + ?line ok = gen_udp:close(S2), + %% + ?line io:format("~s ~p~n", [Hostname,Host]), + ?line S3 = + ok(gen_udp:open(0, [{ifaddr,Host},Active])), + ?line implicit_inet6(S3, Active, Host), + ?line ok = gen_udp:close(S1); + {error,eafnosupport} -> + ?line ok = gen_udp:close(S1), + {skip,"Can not look up IPv6 address"} + end; + _ -> + {skip,"IPv6 not supported"} + end. + +implicit_inet6(S1, Active, Addr) -> + ?line P1 = ok(inet:port(S1)), + ?line S2 = ok(gen_udp:open(0, [inet6,Active])), + ?line P2 = ok(inet:port(S2)), + ?line ok = gen_udp:connect(S2, Addr, P1), + ?line ok = gen_udp:connect(S1, Addr, P2), + ?line {Addr,P2} = ok(inet:peername(S1)), + ?line {Addr,P1} = ok(inet:peername(S2)), + ?line {Addr,P1} = ok(inet:sockname(S1)), + ?line {Addr,P2} = ok(inet:sockname(S2)), + ?line ok = gen_udp:send(S1, Addr, P2, "ping"), + ?line {Addr,P1,"ping"} = ok(gen_udp:recv(S2, 1024, 1000)), + ?line ok = gen_udp:send(S2, Addr, P1, "pong"), + ?line {Addr,P2,"pong"} = ok(gen_udp:recv(S1, 1024)), + ?line ok = gen_udp:close(S2). + + +ok({ok,V}) -> V. |