1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 2007, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
16
%% The SCTP protocol was added 2006
17
%% by Leonid Timochouk <l.timochouk@gmail.com>
18
%% and Serge Aleynikov <serge@hq.idt.net>
19
%% at IDT Corp. Adapted by the OTP team at Ericsson AB.
26
%% This module provides functions for communicating with
27
%% sockets using the SCTP protocol. The implementation assumes that
28
%% the OS kernel supports SCTP providing user-level SCTP Socket API:
29
%% http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13
31
-include("inet_sctp.hrl").
33
-export([open/0,open/1,open/2,close/1]).
34
-export([listen/2,connect/4,connect/5]).
35
-export([eof/2,abort/2]).
36
-export([send/3,send/4,recv/1,recv/2]).
37
-export([error_string/1]).
38
-export([controlling_process/2]).
45
open(Opts) when is_list(Opts) ->
47
case Mod:open(Opts) of
49
erlang:error(badarg, [Opts]);
51
erlang:error(badarg, [Opts]);
54
open(Port) when is_integer(Port) ->
57
erlang:error(badarg, [X]).
59
open(Port, Opts) when is_integer(Port), is_list(Opts) ->
60
open([{port,Port}|Opts]);
62
erlang:error(badarg, [Port,Opts]).
64
close(S) when is_port(S) ->
65
case inet_db:lookup_socket(S) of
71
erlang:error(badarg, [S]).
75
listen(S, Flag) when is_port(S), is_boolean(Flag) ->
76
case inet_db:lookup_socket(S) of
82
erlang:error(badarg, [S,Flag]).
84
connect(S, Addr, Port, Opts) ->
85
connect(S, Addr, Port, Opts, infinity).
87
connect(S, Addr, Port, Opts, Timeout) when is_port(S), is_list(Opts) ->
88
case inet_db:lookup_socket(S) of
90
case Mod:getserv(Port) of
92
try inet:start_timer(Timeout) of
94
try Mod:getaddr(Addr, Timer) of
96
Mod:connect(S, IP, Port, Opts, Timer);
99
inet:stop_timer(Timer)
103
erlang:error(badarg, [S,Addr,Port,Opts,Timeout])
109
connect(S, Addr, Port, Opts, Timeout) ->
110
erlang:error(badarg, [S,Addr,Port,Opts,Timeout]).
114
eof(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
115
eof_or_abort(S, AssocId, eof);
117
erlang:error(badarg, [S,Assoc]).
119
abort(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
120
eof_or_abort(S, AssocId, abort);
122
erlang:error(badarg, [S,Assoc]).
124
eof_or_abort(S, AssocId, Action) ->
125
case inet_db:lookup_socket(S) of
127
Mod:sendmsg(S, #sctp_sndrcvinfo{assoc_id = AssocId,
135
%% Full-featured send. Rarely needed.
136
send(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) ->
137
case inet_db:lookup_socket(S) of
139
Mod:sendmsg(S, SRI, Data);
142
send(S, SRI, Data) ->
143
erlang:error(badarg, [S,SRI,Data]).
145
send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data)
146
when is_port(S), is_integer(Stream) ->
147
case inet_db:lookup_socket(S) of
149
Mod:sendmsg(S, #sctp_sndrcvinfo{
151
assoc_id = AssocId}, Data);
154
send(S, AssocId, Stream, Data)
155
when is_port(S), is_integer(AssocId), is_integer(Stream) ->
156
case inet_db:lookup_socket(S) of
158
Mod:sendmsg(S, #sctp_sndrcvinfo{
160
assoc_id = AssocId}, Data);
163
send(S, AssocChange, Stream, Data) ->
164
erlang:error(badarg, [S,AssocChange,Stream,Data]).
169
recv(S, Timeout) when is_port(S) ->
170
case inet_db:lookup_socket(S) of
172
Mod:recv(S, Timeout);
176
erlang:error(badarg, [S,Timeout]).
183
"Invalid Stream Identifier";
185
"Missing Mandatory Parameter";
187
"Stale Cookie Error";
191
"Unresolvable Address";
193
"Unrecognized Chunk Type";
195
"Invalid Mandatory Parameter";
197
"Unrecognized Parameters";
201
"Cookie Received While Shutting Down";
203
"User Initiated Abort";
204
%% For more info on principal SCTP error codes: phone +44 7981131933
205
error_string(N) when is_integer(N) ->
208
erlang:error(badarg, [X]).
212
controlling_process(S, Pid) when is_port(S), is_pid(Pid) ->
213
inet:udp_controlling_process(S, Pid);
214
controlling_process(S, Pid) ->
215
erlang:error(badarg, [S,Pid]).
217
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221
%% Get the SCTP moudule
222
mod() -> inet_db:sctp_module().
224
%% Get the SCTP module, but option sctp_module|inet|inet6 overrides
225
mod([{sctp_module,Mod}|_]) ->