From bfb350ecc30d44e64ed75512690a0e4fbbb6bc2a Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 20 Sep 2011 09:27:02 +0200 Subject: erts,kernel: Rename operations common to TCP and SCTP --- erts/preloaded/src/prim_inet.erl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 8f2e845b4f..adf64f90df 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -318,7 +318,7 @@ accept_opts(L, S) -> end. async_accept(L, Time) -> - case ctl_cmd(L,?TCP_REQ_ACCEPT, [enc_time(Time)]) of + case ctl_cmd(L,?INET_REQ_ACCEPT, [enc_time(Time)]) of {ok, [R1,R0]} -> {ok, ?u16(R1,R0)}; Error -> Error end. @@ -334,16 +334,13 @@ async_accept(L, Time) -> %% listening) is also accepted: listen(S) -> listen(S, ?LISTEN_BACKLOG). - + +listen(S, true) -> listen(S, ?LISTEN_BACKLOG); +listen(S, false) -> listen(S, 0); listen(S, BackLog) when is_port(S), is_integer(BackLog) -> - case ctl_cmd(S, ?TCP_REQ_LISTEN, [?int16(BackLog)]) of + case ctl_cmd(S, ?INET_REQ_LISTEN, [?int16(BackLog)]) of {ok, _} -> ok; Error -> Error - end; -listen(S, Flag) when is_port(S), is_boolean(Flag) -> - case ctl_cmd(S, ?SCTP_REQ_LISTEN, enc_value(set, bool8, Flag)) of - {ok,_} -> ok; - Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From faea8584311fcb5365c585280e5e9b2364ed121e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 2 Sep 2011 10:38:39 +0200 Subject: erts,kernel: Add type stream sockets to SCTP --- erts/preloaded/src/erl_prim_loader.erl | 8 ++--- erts/preloaded/src/prim_inet.erl | 64 +++++++++++++--------------------- 2 files changed, 29 insertions(+), 43 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl index 0b4db3d9d0..35defde692 100644 --- a/erts/preloaded/src/erl_prim_loader.erl +++ b/erts/preloaded/src/erl_prim_loader.erl @@ -729,7 +729,7 @@ udp_options() -> %% INET version IPv4 addresses %% ll_tcp_connect(LocalPort, IP, RemotePort) -> - case ll_open_set_bind(tcp, ?INET_FAMILY, tcp_options(), + case ll_open_set_bind(tcp, ?INET_FAMILY, stream, tcp_options(), ?INET_ADDRESS, LocalPort) of {ok,S} -> case prim_inet:connect(S, IP, RemotePort, tcp_timeout()) of @@ -743,11 +743,11 @@ ll_tcp_connect(LocalPort, IP, RemotePort) -> %% Open and initialize an udp port for broadcast %% ll_udp_open(P) -> - ll_open_set_bind(udp, ?INET_FAMILY, udp_options(), ?INET_ADDRESS, P). + ll_open_set_bind(udp, ?INET_FAMILY, dgram, udp_options(), ?INET_ADDRESS, P). -ll_open_set_bind(Protocol, Family, SOpts, IP, Port) -> - case prim_inet:open(Protocol, Family) of +ll_open_set_bind(Protocol, Family, Type, SOpts, IP, Port) -> + case prim_inet:open(Protocol, Family, Type) of {ok, S} -> case prim_inet:setopts(S, SOpts) of ok -> diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index adf64f90df..231a5ed4e5 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -25,7 +25,7 @@ %% Primitive inet_drv interface --export([open/1, open/2, fdopen/2, fdopen/3, close/1]). +-export([open/3, fdopen/4, close/1]). -export([bind/3, listen/1, listen/2]). -export([connect/3, connect/4, async_connect/4]). -export([accept/1, accept/2, async_accept/2]). @@ -56,58 +56,44 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% OPEN(tcp | udp | sctp, inet | inet6) -> +%% OPEN(tcp | udp | sctp, inet | inet6, stream | dgram | seqpacket) -> %% {ok, insock()} | %% {error, Reason} %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -open(Protocol) -> open1(Protocol, ?INET_AF_INET). +open(Protocol, Family, Type) -> + open(Protocol, Family, Type, ?INET_REQ_OPEN, []). -open(Protocol, inet) -> open1(Protocol, ?INET_AF_INET); -open(Protocol, inet6) -> open1(Protocol, ?INET_AF_INET6); -open(_, _) -> {error, einval}. +fdopen(Protocol, Family, Type, Fd) when is_integer(Fd) -> + open(Protocol, Family, Type, ?INET_REQ_FDOPEN, ?int32(Fd)). -fdopen(Protocol, Fd) -> fdopen1(Protocol, ?INET_AF_INET, Fd). - -fdopen(Protocol, Fd, inet) -> fdopen1(Protocol, ?INET_AF_INET, Fd); -fdopen(Protocol, Fd, inet6) -> fdopen1(Protocol, ?INET_AF_INET6, Fd); -fdopen(_, _, _) -> {error, einval}. - -open1(Protocol, Family) -> - case open0(Protocol) of - {ok, S} -> - case ctl_cmd(S, ?INET_REQ_OPEN, [Family]) of - {ok, _} -> - {ok,S}; +open(Protocol, Family, Type, Req, Data) -> + Drv = protocol2drv(Protocol), + AF = enc_family(Family), + T = enc_type(Type), + try erlang:open_port({spawn_driver,Drv}, [binary]) of + S -> + case ctl_cmd(S, Req, [AF,T,Data]) of + {ok,_} -> {ok,S}; Error -> - close(S), Error - end; - Error -> Error - end. - -fdopen1(Protocol, Family, Fd) when is_integer(Fd) -> - case open0(Protocol) of - {ok, S} -> - case ctl_cmd(S,?INET_REQ_FDOPEN,[Family,?int32(Fd)]) of - {ok, _} -> {ok,S}; - Error -> close(S), Error - end; - Error -> Error - end. - -open0(Protocol) -> - try erlang:open_port({spawn_driver,protocol2drv(Protocol)}, [binary]) of - Port -> {ok,Port} + close(S), + Error + end catch error:Reason -> {error,Reason} end. +enc_family(inet) -> ?INET_AF_INET; +enc_family(inet6) -> ?INET_AF_INET6. + +enc_type(stream) -> ?INET_TYPE_STREAM; +enc_type(dgram) -> ?INET_TYPE_DGRAM; +enc_type(seqpacket) -> ?INET_TYPE_SEQPACKET. + protocol2drv(tcp) -> "tcp_inet"; protocol2drv(udp) -> "udp_inet"; -protocol2drv(sctp) -> "sctp_inet"; -protocol2drv(_) -> - erlang:error(eprotonosupport). +protocol2drv(sctp) -> "sctp_inet". drv2protocol("tcp_inet") -> tcp; drv2protocol("udp_inet") -> udp; -- cgit v1.2.3 From 1cc7485467b1b4e9efd15259b58e1182d2e9723c Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 2 Sep 2011 10:29:58 +0200 Subject: erts,kernel: Implement gen_sctp:peeloff/2 --- erts/preloaded/src/prim_inet.erl | 83 ++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 33 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 231a5ed4e5..30c1bec292 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -26,7 +26,7 @@ %% Primitive inet_drv interface -export([open/3, fdopen/4, close/1]). --export([bind/3, listen/1, listen/2]). +-export([bind/3, listen/1, listen/2, peeloff/2]). -export([connect/3, connect/4, async_connect/4]). -export([accept/1, accept/2, async_accept/2]). -export([shutdown/2]). @@ -76,7 +76,7 @@ open(Protocol, Family, Type, Req, Data) -> S -> case ctl_cmd(S, Req, [AF,T,Data]) of {ok,_} -> {ok,S}; - Error -> + {error,_}=Error -> close(S), Error end @@ -125,7 +125,7 @@ shutdown_1(S, How) -> shutdown_2(S, How) -> case ctl_cmd(S, ?TCP_REQ_SHUTDOWN, [How]) of {ok, []} -> ok; - Error -> Error + {error,_}=Error -> Error end. shutdown_pend_loop(S, N0) -> @@ -181,7 +181,7 @@ close_pend_loop(S, N) -> bind(S,IP,Port) when is_port(S), is_integer(Port), Port >= 0, Port =< 65535 -> case ctl_cmd(S,?INET_REQ_BIND,[?int16(Port),ip_to_bytes(IP)]) of {ok, [P1,P0]} -> {ok, ?u16(P1, P0)}; - Error -> Error + {error,_}=Error -> Error end; %% Multi-homed "bind": sctp_bindx(). The Op is 'add' or 'remove'. @@ -208,7 +208,7 @@ bindx(S, AddFlag, Addrs) -> {IP, Port} <- Addrs]], case ctl_cmd(S, ?SCTP_REQ_BINDX, Args) of {ok,_} -> {ok, S}; - Error -> Error + {error,_}=Error -> Error end; _ -> {error, einval} end. @@ -251,7 +251,7 @@ async_connect(S, IP, Port, Time) -> case ctl_cmd(S, ?INET_REQ_CONNECT, [enc_time(Time),?int16(Port),ip_to_bytes(IP)]) of {ok, [R1,R0]} -> {ok, S, ?u16(R1,R0)}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -306,7 +306,7 @@ accept_opts(L, S) -> async_accept(L, Time) -> case ctl_cmd(L,?INET_REQ_ACCEPT, [enc_time(Time)]) of {ok, [R1,R0]} -> {ok, ?u16(R1,R0)}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -326,7 +326,24 @@ listen(S, false) -> listen(S, 0); listen(S, BackLog) when is_port(S), is_integer(BackLog) -> case ctl_cmd(S, ?INET_REQ_LISTEN, [?int16(BackLog)]) of {ok, _} -> ok; - Error -> Error + {error,_}=Error -> Error + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% PEELOFF(insock(), AssocId) -> {ok,outsock()} | {error, Reason} +%% +%% SCTP: Peel off one association into a type stream socket +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +peeloff(S, AssocId) -> + case ctl_cmd(S, ?SCTP_REQ_PEELOFF, [?int32(AssocId)]) of + inet_reply -> + receive + {inet_reply,S,Res} -> Res + end; + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -378,12 +395,12 @@ sendto(S, IP, Port, Data) when is_port(S), Port >= 0, Port =< 65535 -> true -> receive {inet_reply,S,Reply} -> - ?DBG_FORMAT("prim_inet:send() -> ~p~n", [Reply]), + ?DBG_FORMAT("prim_inet:sendto() -> ~p~n", [Reply]), Reply end catch error:_ -> - ?DBG_FORMAT("prim_inet:send() -> {error,einval}~n", []), + ?DBG_FORMAT("prim_inet:sendto() -> {error,einval}~n", []), {error,einval} end. @@ -438,7 +455,7 @@ recv0(S, Length, Time) when is_port(S), is_integer(Length), Length >= 0 -> async_recv(S, Length, Time) -> case ctl_cmd(S, ?TCP_REQ_RECV, [enc_time(Time), ?int32(Length)]) of {ok,[R1,R0]} -> {ok, ?u16(R1,R0)}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -484,7 +501,7 @@ recvfrom0(S, Length, Time) {inet_async, S, Ref, Error={error, _}} -> Error end; - Error -> + {error,_}=Error -> Error % Front-end error end; recvfrom0(_, _, _) -> {error,einval}. @@ -500,18 +517,18 @@ peername(S) when is_port(S) -> {ok, [F, P1,P0 | Addr]} -> {IP, _} = get_ip(F, Addr), {ok, { IP, ?u16(P1, P0) }}; - Error -> Error + {error,_}=Error -> Error end. setpeername(S, {IP,Port}) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_SETPEER, [?int16(Port),ip_to_bytes(IP)]) of {ok,[]} -> ok; - Error -> Error + {error,_}=Error -> Error end; setpeername(S, undefined) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_SETPEER, []) of {ok,[]} -> ok; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -525,18 +542,18 @@ sockname(S) when is_port(S) -> {ok, [F, P1, P0 | Addr]} -> {IP, _} = get_ip(F, Addr), {ok, { IP, ?u16(P1, P0) }}; - Error -> Error + {error,_}=Error -> Error end. setsockname(S, {IP,Port}) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_SETNAME, [?int16(Port),ip_to_bytes(IP)]) of {ok,[]} -> ok; - Error -> Error + {error,_}=Error -> Error end; setsockname(S, undefined) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_SETNAME, []) of {ok,[]} -> ok; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -556,7 +573,7 @@ setopts(S, Opts) when is_port(S) -> {ok, Buf} -> case ctl_cmd(S, ?INET_REQ_SETOPTS, Buf) of {ok, _} -> ok; - Error -> Error + {error,_}=Error -> Error end; Error -> Error end. @@ -582,12 +599,12 @@ getopts(S, Opts) when is_port(S), is_list(Opts) -> {ok,Rep} -> %% Non-SCTP: "Rep" contains the encoded option vals: decode_opt_val(Rep); - {error,sctp_reply} -> + inet_reply -> %% SCTP: Need to receive the full value: receive {inet_reply,S,Res} -> Res end; - Error -> Error + {error,_}=Error -> Error end; Error -> Error end. @@ -716,7 +733,7 @@ getifaddrs_ifget(S, IFs, IF, FlagsVals, Opts) -> getiflist(S) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_GETIFLIST, []) of {ok, Data} -> {ok, build_iflist(Data)}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -734,7 +751,7 @@ ifget(S, Name, Opts) -> {ok, Buf2} -> case ctl_cmd(S, ?INET_REQ_IFGET, [Buf1,Buf2]) of {ok, Data} -> decode_ifopts(Data,[]); - Error -> Error + {error,_}=Error -> Error end; Error -> Error end; @@ -756,7 +773,7 @@ ifset(S, Name, Opts) -> {ok, Buf2} -> case ctl_cmd(S, ?INET_REQ_IFSET, [Buf1,Buf2]) of {ok, _} -> ok; - Error -> Error + {error,_}=Error -> Error end; Error -> Error end; @@ -784,7 +801,7 @@ subscribe(S, Sub) when is_port(S), is_list(Sub) -> {ok, Bytes} -> case ctl_cmd(S, ?INET_REQ_SUBSCRIBE, Bytes) of {ok, Data} -> decode_subs(Data); - Error -> Error + {error,_}=Error -> Error end; Error -> Error end. @@ -802,7 +819,7 @@ getstat(S, Stats) when is_port(S), is_list(Stats) -> {ok, Bytes} -> case ctl_cmd(S, ?INET_REQ_GETSTAT, Bytes) of {ok, Data} -> decode_stats(Data); - Error -> Error + {error,_}=Error -> Error end; Error -> Error end. @@ -818,7 +835,7 @@ getstat(S, Stats) when is_port(S), is_list(Stats) -> getfd(S) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_GETFD, []) of {ok, [S3,S2,S1,S0]} -> {ok, ?u32(S3,S2,S1,S0)}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -856,7 +873,7 @@ gettype(S) when is_port(S) -> _ -> undefined end, {ok, {Family, Type}}; - Error -> Error + {error,_}=Error -> Error end. getprotocol(S) when is_port(S) -> @@ -884,7 +901,7 @@ getstatus(S) when is_port(S) -> case ctl_cmd(S, ?INET_REQ_GETSTATUS, []) of {ok, [S3,S2,S1,S0]} -> {ok, dec_status(?u32(S3,S2,S1,S0))}; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -926,7 +943,7 @@ getservbyname1(S,Name,Proto) -> case ctl_cmd(S, ?INET_REQ_GETSERVBYNAME, [L1,Name,L2,Proto]) of {ok, [P1,P0]} -> {ok, ?u16(P1,P0)}; - Error -> + {error,_}=Error -> Error end end. @@ -954,7 +971,7 @@ getservbyport1(S,Port,Proto) -> true -> case ctl_cmd(S, ?INET_REQ_GETSERVBYPORT, [?int16(Port),L,Proto]) of {ok, Name} -> {ok, Name}; - Error -> Error + {error,_}=Error -> Error end end. @@ -968,7 +985,7 @@ getservbyport1(S,Port,Proto) -> unrecv(S, Data) -> case ctl_cmd(S, ?TCP_REQ_UNRECV, Data) of {ok, _} -> ok; - Error -> Error + {error,_}=Error -> Error end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2146,7 +2163,7 @@ ctl_cmd(Port, Cmd, Args) -> Result = try erlang:port_control(Port, Cmd, Args) of [?INET_REP_OK|Reply] -> {ok,Reply}; - [?INET_REP_SCTP] -> {error,sctp_reply}; + [?INET_REP] -> inet_reply; [?INET_REP_ERROR|Err] -> {error,list_to_atom(Err)} catch error:_ -> {error,einval} -- cgit v1.2.3 From 8a571dad575b2812ad51a80171cd29e73d64d21b Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 17 Nov 2011 15:09:22 +0100 Subject: Update primary bootstrap and preloaded files --- erts/preloaded/ebin/erl_prim_loader.beam | Bin 50320 -> 53080 bytes erts/preloaded/ebin/prim_inet.beam | Bin 65000 -> 69848 bytes 2 files changed, 0 insertions(+), 0 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam index ffee1f489f..fe91a604b5 100644 Binary files a/erts/preloaded/ebin/erl_prim_loader.beam and b/erts/preloaded/ebin/erl_prim_loader.beam differ diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index 22c51c79c0..0e5cb1867f 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ -- cgit v1.2.3 From 4f8e3e94357cd4730c9e3135f2bafd9b6d4fd13e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 28 Sep 2011 11:48:08 +0200 Subject: erts,kernel: Return eprotonosupport when SCTP is not supported It is better that gen_sctp:open/0-2 returns the informative Posix return code {error,eprotonosupport} than previously {error,badarg} when SCTP is not supported since it is so platform dependent. --- erts/preloaded/src/prim_inet.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 30c1bec292..f144f73d68 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -81,7 +81,9 @@ open(Protocol, Family, Type, Req, Data) -> Error end catch - error:Reason -> {error,Reason} + %% The only (?) way to get here is to try to open + %% the sctp driver when it does not exist + error:badarg -> {error,eprotonosupport} end. enc_family(inet) -> ?INET_AF_INET; -- cgit v1.2.3 From 0bdfac2b5a30af4cd4f725bd173bec7f2bd80582 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 17 Nov 2011 15:22:59 +0100 Subject: Update preloaded files --- erts/preloaded/ebin/prim_inet.beam | Bin 69848 -> 69916 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index 0e5cb1867f..d44bbbbd27 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ -- cgit v1.2.3