diff options
Diffstat (limited to 'lib/kernel')
-rw-r--r-- | lib/kernel/src/gen_sctp.erl | 8 | ||||
-rw-r--r-- | lib/kernel/src/inet6_sctp.erl | 23 | ||||
-rw-r--r-- | lib/kernel/src/inet_sctp.erl | 21 | ||||
-rw-r--r-- | lib/kernel/src/net_kernel.erl | 4 | ||||
-rw-r--r-- | lib/kernel/test/erl_distribution_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/kernel/test/gen_sctp_SUITE.erl | 189 | ||||
-rw-r--r-- | lib/kernel/vsn.mk | 19 |
7 files changed, 226 insertions, 40 deletions
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 5a31e3976f..a1542ab507 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -166,18 +166,14 @@ send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data) when is_port(S), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocId, Stream, Data) when is_port(S), is_integer(AssocId), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocChange, Stream, Data) -> diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl index 5c49c4fec3..5bf3fca647 100644 --- a/lib/kernel/src/inet6_sctp.erl +++ b/lib/kernel/src/inet6_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-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 @@ -32,7 +32,7 @@ -define(FAMILY, inet6). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -71,5 +71,24 @@ connect(S, Addr, Port, Opts, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl index 795bf83807..de74b573bd 100644 --- a/lib/kernel/src/inet_sctp.erl +++ b/lib/kernel/src/inet_sctp.erl @@ -31,7 +31,7 @@ -define(FAMILY, inet). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -141,5 +141,24 @@ connect_get_assoc(S, Addr, Port, Active, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 0e5cc8c2c6..f5e2820bbe 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -500,8 +500,8 @@ handle_call({new_ticktime,T,TP}, From, #state{tick = #tick{ticker = Tckr, time = T, how = How}}}, From); -handle_call({new_ticktime,From,_}, - _, +handle_call({new_ticktime,_T,_TP}, + From, #state{tick = #tick_change{time = T}} = State) -> async_reply({reply, {ongoing_change_to, T}, State}, From); diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl index d15f6aa0d5..21a96f804a 100644 --- a/lib/kernel/test/erl_distribution_SUITE.erl +++ b/lib/kernel/test/erl_distribution_SUITE.erl @@ -273,6 +273,7 @@ tick_change(Config) when is_list(Config) -> ?line PaDir = filename:dirname(code:which(?MODULE)), ?line [BN, CN] = get_nodenames(2, tick_change), ?line DefaultTT = net_kernel:get_net_ticktime(), + ?line unchanged = net_kernel:set_net_ticktime(DefaultTT, 60), ?line case DefaultTT of I when is_integer(I) -> ?line ok; _ -> ?line ?t:fail(DefaultTT) @@ -377,6 +378,7 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) -> end, ?line change_initiated = net_kernel:set_net_ticktime(TT,20), + ?line {ongoing_change_to,_} = net_kernel:set_net_ticktime(TT,20), ?line sleep(3), ?line change_initiated = rpc:call(B,net_kernel,set_net_ticktime,[TT,15]), ?line sleep(7), diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index fad8c7398b..eb06d4324b 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -23,12 +23,16 @@ %%-compile(export_all). --export([all/1,init_per_testcase/2,fin_per_testcase/2, - basic/1,api_open_close/1,api_listen/1,api_connect_init/1, - xfer_min/1,xfer_active/1]). +-export([all/1,init_per_testcase/2,fin_per_testcase/2]). +-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]). all(suite) -> - [basic,api_open_close,api_listen,api_connect_init,xfer_min,xfer_active]. + [basic, + api_open_close,api_listen,api_connect_init,api_opts, + xfer_min,xfer_active,def_sndrcvinfo]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(15)), @@ -39,6 +43,10 @@ fin_per_testcase(_Func, Config) -> +-define(LOGVAR(Var), begin io:format(??Var" = ~p~n", [Var]) end). + + + basic(doc) -> "Hello world"; basic(suite) -> @@ -214,12 +222,17 @@ xfer_active(Config) when is_list(Config) -> end, ?line ok = gen_sctp:close(Sb), ?line receive - {sctp,Sa,Loopback,Pb, - {[], - #sctp_assoc_change{state=comm_lost, - assoc_id=SaAssocId}}} -> ok - after 17 -> ok %% On Solaris this does not arrive - end, + {sctp,Sa,Loopback,Pb, + {[], + #sctp_assoc_change{state=comm_lost, + assoc_id=SaAssocId}}} -> ok + after Timeout -> + ?line test_server:fail({unexpected,flush()}) + end, + ?line receive + {sctp_error,Sa,enotconn} -> ok % Solaris + after 17 -> ok %% Only happens on Solaris + end, ?line ok = gen_sctp:close(Sa), %% ?line receive @@ -228,6 +241,148 @@ xfer_active(Config) when is_list(Config) -> end, ok. +def_sndrcvinfo(doc) -> + "Test that #sctp_sndrcvinfo{} parameters set on a socket " + "are used by gen_sctp:send/4"; +def_sndrcvinfo(suite) -> + []; +def_sndrcvinfo(Config) when is_list(Config) -> + ?line Loopback = {127,0,0,1}, + ?line Data = <<"What goes up, must come down.">>, + %% + ?line S1 = + ok(gen_sctp:open( + 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])), + ?LOGVAR(S1), + ?line P1 = + ok(inet:port(S1)), + ?LOGVAR(P1), + ?line #sctp_sndrcvinfo{ppid=17, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line ok = + gen_sctp:listen(S1, true), + %% + ?line S2 = + ok(gen_sctp:open()), + ?LOGVAR(S2), + ?line P2 = + ok(inet:port(S2)), + ?LOGVAR(P2), + ?line #sctp_sndrcvinfo{ppid=0, context=0, timetolive=0, assoc_id=0} = + getopt(S2, sctp_default_send_param), + %% + ?line #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S2AssocId} = S2AssocChange = + ok(gen_sctp:connect(S2, Loopback, P1, [])), + ?LOGVAR(S2AssocChange), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback, P2,[], + #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S1AssocId}} -> + ?LOGVAR(S1AssocId) + end, + ?line #sctp_sndrcvinfo{ + ppid=17, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=0, context=0, timetolive=0, assoc_id=S2AssocId} = + getopt( + S2, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S2AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 1, <<"1: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=1, ppid=17, context=0, assoc_id=S2AssocId}], + <<"1: ",Data/binary>>} -> ok + end, + %% + ?line ok = + setopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{ppid=18}), + ?line ok = + setopt( + S1, sctp_default_send_param, + #sctp_sndrcvinfo{ppid=19, assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=18, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line #sctp_sndrcvinfo{ + ppid=19, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 0, <<"2: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=0, ppid=19, context=0, assoc_id=S2AssocId}], + <<"2: ",Data/binary>>} -> ok + end, + ?line ok = + gen_sctp:send(S2, S2AssocChange, 1, <<"3: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok; + {Loopback,P2,[], + #sctp_paddr_change{ + addr={Loopback,_}, state=addr_available, + error=0, assoc_id=S1AssocId}} -> + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, + assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok + end + end, + ?line ok = + gen_sctp:send( + S2, + #sctp_sndrcvinfo{stream=0, ppid=20, assoc_id=S2AssocId}, + <<"4: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=0, ppid=20, context=0, assoc_id=S1AssocId}], + <<"4: ",Data/binary>>} -> ok + end, + %% + ?line ok = + gen_sctp:close(S1), + ?line ok = + gen_sctp:close(S2), + ?line receive + Msg -> + test_server:fail({received,Msg}) + after 17 -> ok + end, + ok. + +getopt(S, Opt) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [Opt]), + Val. + +getopt(S, Opt, Param) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [{Opt,Param}]), + Val. + +setopt(S, Opt, Val) -> + inet:setopts(S, [{Opt,Val}]). + +ok({ok,X}) -> + io:format("OK: ~p~n", [X]), + X. + flush() -> receive Msg -> @@ -382,3 +537,17 @@ api_connect_init(Config) when is_list(Config) -> ?line ok = gen_sctp:close(Sa), ?line ok = gen_sctp:close(Sb), ok. + +api_opts(doc) -> + "Test socket options"; +api_opts(suite) -> + []; +api_opts(Config) when is_list(Config) -> + ?line {ok,S} = gen_sctp:open(0), + ?line OSType = os:type(), + ?line case {inet:setopts(S, [{linger,{true,2}}]),OSType} of + {ok,_} -> + ok; + {{error,einval},{unix,sunos}} -> + ok + end. diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 9a191f9aeb..651d082379 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1,20 +1 @@ -# -# %CopyrightBegin% -# -# 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 -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# %CopyrightEnd% -# - KERNEL_VSN = 2.14.1 |