1gen_sctp(3) Erlang Module Definition gen_sctp(3)
2
3
4
6 gen_sctp - Functions for communicating with sockets using the SCTP
7 protocol.
8
10 This module provides functions for communicating with sockets using the
11 SCTP protocol. The implementation assumes that the OS kernel supports
12 SCTP (RFC 2960) through the user-level Sockets API Extensions.
13
14 During development, this implementation was tested on:
15
16 * Linux Fedora Core 5.0 (kernel 2.6.15-2054 or later is needed)
17
18 * Solaris 10, 11
19
20 During OTP adaptation it was tested on:
21
22 * SUSE Linux Enterprise Server 10 (x86_64) kernel 2.6.16.27-0.6-smp,
23 with lksctp-tools-1.0.6
24
25 * Briefly on Solaris 10
26
27 * SUSE Linux Enterprise Server 10 Service Pack 1 (x86_64) kernel
28 2.6.16.54-0.2.3-smp with lksctp-tools-1.0.7
29
30 * FreeBSD 8.2
31
32 This module was written for one-to-many style sockets (type seqpacket).
33 With the addition of peeloff/2, one-to-one style sockets (type stream)
34 were introduced.
35
36 Record definitions for this module can be found using:
37
38 -include_lib("kernel/include/inet_sctp.hrl").
39
40 These record definitions use the "new" spelling 'adaptation', not the
41 deprecated 'adaption', regardless of which spelling the underlying C
42 API uses.
43
45 Exported data types
46 assoc_id()
47
48 An opaque term returned in, for example, #sctp_paddr_change{},
49 which identifies an association for an SCTP socket. The term is
50 opaque except for the special value 0, which has a meaning such
51 as "the whole endpoint" or "all future associations".
52
53 option() = elementary_option() | record_option()
54
55 One of the SCTP Socket Options used to set an option.
56
57 option_name() =
58 elementary_option_name() | record_option() | ro_option()
59
60 An option name or one of the SCTP Socket Options used to get an
61 option.
62
63 option_value() =
64 elementary_option() | record_option() | ro_option()
65
66 One of the SCTP Socket Options as returned when getting an op‐
67 tion.
68
69 sctp_socket()
70
71 Socket identifier returned from open/*.
72
74 Internal data types
75 elementary_option() =
76 {active, true | false | once | -32768..32767} |
77 {buffer, integer() >= 0} |
78 {debug, boolean()} |
79 {dontroute, boolean()} |
80 {high_msgq_watermark, integer() >= 1} |
81 {linger, {boolean(), integer() >= 0}} |
82 {low_msgq_watermark, integer() >= 1} |
83 {mode, list | binary} |
84 list | binary |
85 {priority, integer() >= 0} |
86 {recbuf, integer() >= 0} |
87 {reuseaddr, boolean()} |
88 {ipv6_v6only, boolean()} |
89 {sndbuf, integer() >= 0} |
90 {sctp_autoclose, integer() >= 0} |
91 {sctp_disable_fragments, boolean()} |
92 {sctp_i_want_mapped_v4_addr, boolean()} |
93 {sctp_maxseg, integer() >= 0} |
94 {sctp_nodelay, boolean()} |
95 {tos, integer() >= 0} |
96 {tclass, integer() >= 0} |
97 {ttl, integer() >= 0} |
98 {recvtos, boolean()} |
99 {recvtclass, boolean()} |
100 {recvttl, boolean()}
101
102 elementary_option_name() =
103 active | buffer | debug | dontroute | high_msgq_watermark |
104 linger | low_msgq_watermark | mode | priority | recbuf |
105 reuseaddr | ipv6_v6only | sctp_autoclose |
106 sctp_disable_fragments | sctp_i_want_mapped_v4_addr |
107 sctp_maxseg | sctp_nodelay | sndbuf | tos | tclass | ttl |
108 recvtos | recvtclass | recvttl
109
110 record_option() =
111 {sctp_adaptation_layer, #sctp_setadaptation{}} |
112 {sctp_associnfo, #sctp_assocparams{}} |
113 {sctp_default_send_param, #sctp_sndrcvinfo{}} |
114 {sctp_delayed_ack_time, #sctp_assoc_value{}} |
115 {sctp_events, #sctp_event_subscribe{}} |
116 {sctp_initmsg, #sctp_initmsg{}} |
117 {sctp_peer_addr_params, #sctp_paddrparams{}} |
118 {sctp_primary_addr, #sctp_prim{}} |
119 {sctp_rtoinfo, #sctp_rtoinfo{}} |
120 {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}
121
122 ro_option() =
123 {sctp_get_peer_addr_info, #sctp_paddrinfo{}} |
124 {sctp_status, #sctp_status{}}
125
127 abort(Socket, Assoc) -> ok | {error, inet:posix()}
128
129 Types:
130
131 Socket = sctp_socket()
132 Assoc = #sctp_assoc_change{}
133
134 Abnormally terminates the association specified by Assoc, with‐
135 out flushing of unsent data. The socket itself remains open.
136 Other associations opened on this socket are still valid, and
137 the socket can be used in new associations.
138
139 close(Socket) -> ok | {error, inet:posix()}
140
141 Types:
142
143 Socket = sctp_socket()
144
145 Closes the socket and all associations on it. The unsent data is
146 flushed as in eof/2. The close/1 call is blocking or otherwise
147 depending of the value of the linger socket option. If close
148 does not linger or linger time-out expires, the call returns and
149 the data is flushed in the background.
150
151 connect(Socket, SockAddr, Opts) ->
152 {ok, #sctp_assoc_change{state = comm_up}} |
153 {error, #sctp_assoc_change{state = cant_assoc}} |
154 {error, inet:posix()}
155
156 Types:
157
158 Socket = sctp_socket()
159 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
160 Opts = [Opt :: option()]
161
162 Same as connect(Socket, SockAddr, Opts, infinity).
163
164 connect(Socket, SockAddr, Opts, Timeout) ->
165 {ok, #sctp_assoc_change{state = comm_up}} |
166 {error, #sctp_assoc_change{state = cant_assoc}} |
167 {error, inet:posix()}
168
169 Types:
170
171 Socket = sctp_socket()
172 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
173 Opts = [Opt :: option()]
174 Timeout = timeout()
175
176 This is conceptually the same as connect/5, only with the dif‐
177 ference that we use a socket address, socket:sockaddr_in() or
178 socket:sockaddr_in6() instead of an address (inet:ip_address()
179 or inet:hostname()) and port-number.
180
181 connect(Socket, Addr, Port, Opts) ->
182 {ok, #sctp_assoc_change{state = comm_up}} |
183 {error, #sctp_assoc_change{state = cant_assoc}} |
184 {error, inet:posix()}
185
186 Types:
187
188 Socket = sctp_socket()
189 Addr = inet:ip_address() | inet:hostname()
190 Port = inet:port_number()
191 Opts = [Opt :: option()]
192
193 Same as connect(Socket, Addr, Port, Opts, infinity).
194
195 connect(Socket, Addr, Port, Opts, Timeout) ->
196 {ok, #sctp_assoc_change{state = comm_up}} |
197 {error, #sctp_assoc_change{state = cant_assoc}} |
198 {error, inet:posix()}
199
200 Types:
201
202 Socket = sctp_socket()
203 Addr = inet:ip_address() | inet:hostname()
204 Port = inet:port_number()
205 Opts = [Opt :: option()]
206 Timeout = timeout()
207
208 Establishes a new association for socket Socket, with the peer
209 (SCTP server socket) specified by Addr and Port. Timeout, is ex‐
210 pressed in milliseconds. A socket can be associated with multi‐
211 ple peers.
212
213 Warning:
214 Using a value of Timeout less than the maximum time taken by the
215 OS to establish an association (around 4.5 minutes if the de‐
216 fault values from RFC 4960 are used), can result in inconsistent
217 or incorrect return values. This is especially relevant for as‐
218 sociations sharing the same Socket (that is, source address and
219 port), as the controlling process blocks until connect/* re‐
220 turns. connect_init/* provides an alternative without this limi‐
221 tation.
222
223
224 The result of connect/* is an #sctp_assoc_change{} event that
225 contains, in particular, the new Association ID:
226
227 #sctp_assoc_change{
228 state = atom(),
229 error = integer(),
230 outbound_streams = integer(),
231 inbound_streams = integer(),
232 assoc_id = assoc_id()
233 }
234
235 The number of outbound and inbound streams can be set by giving
236 an sctp_initmsg option to connect as in:
237
238 connect(Socket, Ip, Port>,
239 [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
240 max_instreams=MaxInStreams}}])
241
242 All options Opt are set on the socket before the association is
243 attempted. If an option record has undefined field values, the
244 options record is first read from the socket for those values.
245 In effect, Opt option records only define field values to change
246 before connecting.
247
248 The returned outbound_streams and inbound_streams are the stream
249 numbers on the socket. These can be different from the requested
250 values (OutStreams and MaxInStreams, respectively) if the peer
251 requires lower values.
252
253 state can have the following values:
254
255 comm_up:
256 Association is successfully established. This indicates a
257 successful completion of connect.
258
259 cant_assoc:
260 The association cannot be established (connect/* failure).
261
262 Other states do not normally occur in the output from connect/*.
263 Rather, they can occur in #sctp_assoc_change{} events received
264 instead of data in recv/* calls. All of them indicate losing the
265 association because of various error conditions, and are listed
266 here for the sake of completeness:
267
268 comm_lost:
269
270
271 restart:
272
273
274 shutdown_comp:
275
276
277 Field error can provide more detailed diagnostics. The error
278 field value can be converted into a string using error_string/1.
279
280 connect_init(Socket, SockAddr, Opts) -> ok | {error, inet:posix()}
281
282 Types:
283
284 Socket = sctp_socket()
285 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
286 Opts = [option()]
287
288 Same as connect_init(Socket, SockAddr, Opts, infinity).
289
290 connect_init(Socket, SockAddr, Opts, Timeout) ->
291 ok | {error, inet:posix()}
292
293 Types:
294
295 Socket = sctp_socket()
296 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
297 Opts = [option()]
298 Timeout = timeout()
299
300 This is conceptually the same as connect_init/5, only with the
301 difference that we use a socket address, socket:sockaddr_in() or
302 socket:sockaddr_in6() instead of an address (inet:ip_address()
303 or inet:hostname()) and port-number.
304
305 connect_init(Socket, Addr, Port, Opts) ->
306 ok | {error, inet:posix()}
307
308 Types:
309
310 Socket = sctp_socket()
311 Addr = inet:ip_address() | inet:hostname()
312 Port = inet:port_number()
313 Opts = [option()]
314
315 Same as connect_init(Socket, Addr, Port, Opts, infinity).
316
317 connect_init(Socket, Addr, Port, Opts, Timeout) ->
318 ok | {error, inet:posix()}
319
320 Types:
321
322 Socket = sctp_socket()
323 Addr = inet:ip_address() | inet:hostname()
324 Port = inet:port_number()
325 Opts = [option()]
326 Timeout = timeout()
327
328 Initiates a new association for socket Socket, with the peer
329 (SCTP server socket) specified by Addr and Port.
330
331 The fundamental difference between this API and connect/* is
332 that the return value is that of the underlying OS connect(2)
333 system call. If ok is returned, the result of the association
334 establishment is received by the calling process as an #sctp_as‐
335 soc_change{} event. The calling process must be prepared to re‐
336 ceive this, or poll for it using recv/*, depending on the value
337 of the active option.
338
339 The parameters are as described in connect/*, except the Timeout
340 value.
341
342 The timer associated with Timeout only supervises IP resolution
343 of Addr.
344
345 connectx_init(Socket, SockAddrs, Opts) ->
346 {ok, assoc_id()} | {error, inet:posix()}
347
348 Types:
349
350 Socket = sctp_socket()
351 SockAddrs =
352 [{inet:ip_address(), inet:port_number()} |
353 inet:family_address() |
354 socket:sockaddr_in() |
355 socket:sockaddr_in6()]
356 Opts = [option()]
357
358 Similar to connectx_init/5 except using socket addresses, and
359 not having a Timeout. Since the addresses do not need lookup and
360 the connect is non-blocking this call returns immediately.
361
362 The value of each socket address port must be the same or zero.
363 At least one socket address must have a non-zero port
364
365 connectx_init(Socket, Addrs, Port, Opts) ->
366 {ok, assoc_id()} | {error, inet:posix()}
367
368 Types:
369
370 Socket = sctp_socket()
371 Addrs = [inet:ip_address() | inet:hostname()]
372 Port = inet:port_number() | atom()
373 Opts = [option()]
374
375 Same as connectx_init(Socket, Addrs, Port, Opts, infinity).
376
377 connectx_init(Socket, Addrs, Port, Opts, Timeout) ->
378 {ok, assoc_id()} | {error, inet:posix()}
379
380 Types:
381
382 Socket = sctp_socket()
383 Addrs = [inet:ip_address() | inet:hostname()]
384 Port = inet:port_number() | atom()
385 Opts = [option()]
386 Timeout = timeout()
387
388 Initiates a new association for socket Socket, with the peer
389 (SCTP server socket) specified by Addrs and Port.
390
391 This API is similar to connect_init/* except the underlying OS
392 sctp_connectx(3) system call is used.
393
394 If successful, the association ID is returned which will be re‐
395 ceived in a subsequent #sctp_assoc_change{} event.
396
397 The parameters are as described in connect_init/5
398
399 NOTE: This API allows the OS to use all Addrs when establishing
400 an association, but does not guarantee it will. Therefore, if
401 the connection fails the user may want to rotate the order of
402 addresses for a subsequent call.
403
404 controlling_process(Socket, Pid) -> ok | {error, Reason}
405
406 Types:
407
408 Socket = sctp_socket()
409 Pid = pid()
410 Reason = closed | not_owner | badarg | inet:posix()
411
412 Assigns a new controlling process Pid to Socket. Same implemen‐
413 tation as gen_udp:controlling_process/2.
414
415 eof(Socket, Assoc) -> ok | {error, Reason}
416
417 Types:
418
419 Socket = sctp_socket()
420 Assoc = #sctp_assoc_change{}
421 Reason = term()
422
423 Gracefully terminates the association specified by Assoc, with
424 flushing of all unsent data. The socket itself remains open.
425 Other associations opened on this socket are still valid. The
426 socket can be used in new associations.
427
428 error_string(ErrorNumber) -> ok | string() | unknown_error
429
430 Types:
431
432 ErrorNumber = integer()
433
434 Translates an SCTP error number from, for example, #sctp_re‐
435 mote_error{} or #sctp_send_failed{} into an explanatory string,
436 or one of the atoms ok for no error or undefined for an unrecog‐
437 nized error.
438
439 listen(Socket, IsServer) -> ok | {error, Reason}
440
441 listen(Socket, Backlog) -> ok | {error, Reason}
442
443 Types:
444
445 Socket = sctp_socket()
446 Backlog = integer()
447 Reason = term()
448
449 Sets up a socket to listen on the IP address and port number it
450 is bound to.
451
452 For type seqpacket, sockets (the default) IsServer must be true
453 or false. In contrast to TCP, there is no listening queue length
454 in SCTP. If IsServer is true, the socket accepts new associa‐
455 tions, that is, it becomes an SCTP server socket.
456
457 For type stream, sockets Backlog define the backlog queue length
458 just like in TCP.
459
460 open() -> {ok, Socket} | {error, inet:posix()}
461
462 open(Port) -> {ok, Socket} | {error, inet:posix()}
463
464 open(Opts) -> {ok, Socket} | {error, inet:posix()}
465
466 open(Port, Opts) -> {ok, Socket} | {error, inet:posix()}
467
468 Types:
469
470 Opts = [Opt]
471 Opt =
472 {ifaddr, IP | SockAddr} |
473 {ip, IP} |
474 {port, Port} |
475 inet:address_family() |
476 {type, SockType} |
477 {netns, file:filename_all()} |
478 {bind_to_device, binary()} |
479 option()
480 IP = inet:ip_address() | any | loopback
481 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
482 Port = inet:port_number()
483 SockType = seqpacket | stream
484 Socket = sctp_socket()
485
486 Creates an SCTP socket and binds it to the local addresses spec‐
487 ified by all {ip,IP} (or synonymously {ifaddr,IP}) options (this
488 feature is called SCTP multi-homing). The default IP and Port
489 are any and 0, meaning bind to all local addresses on any free
490 port.
491
492 It is also possible to use {ifaddr, SockAddr}, in which case it
493 takes precedence over the ip and port options. These options can
494 however be used to update the address and port of ifaddr (if
495 they occur after ifaddr in the options list), although this is
496 not recommended.
497
498 Other options:
499
500 inet6:
501 Sets up the socket for IPv6.
502
503 inet:
504 Sets up the socket for IPv4. This is the default.
505
506 A default set of socket options is used. In particular, the
507 socket is opened in binary and passive mode, with SockType seq‐
508 packet, and with reasonably large kernel and driver buffers.
509
510 If the socket is in passive mode data can be received through
511 the recv/1,2 calls.
512
513 If the socket is in active mode data received data is delivered
514 to the controlling process as messages:
515
516 {sctp, Socket, FromIP, FromPort, {AncData, Data}}
517
518
519 See recv/1,2 for a description of the message fields.
520
521 Note:
522 This message format unfortunately differs slightly from the
523 gen_udp message format with ancillary data, and from the
524 recv/1,2 return tuple format.
525
526
527 peeloff(Socket, Assoc) -> {ok, NewSocket} | {error, Reason}
528
529 Types:
530
531 Socket = sctp_socket()
532 Assoc = #sctp_assoc_change{} | assoc_id()
533 NewSocket = sctp_socket()
534 Reason = term()
535
536 Branches off an existing association Assoc in a socket Socket of
537 type seqpacket (one-to-many style) into a new socket NewSocket
538 of type stream (one-to-one style).
539
540 The existing association argument Assoc can be either a
541 #sctp_assoc_change{} record as returned from, for example,
542 recv/*, connect/*, or from a listening socket in active mode. It
543 can also be just the field assoc_id integer from such a record.
544
545 recv(Socket) ->
546 {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
547
548 recv(Socket, Timeout) ->
549 {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
550
551 Types:
552
553 Socket = sctp_socket()
554 Timeout = timeout()
555 FromIP = inet:ip_address()
556 FromPort = inet:port_number()
557 AncData = [#sctp_sndrcvinfo{} | inet:ancillary_data()]
558 Data =
559 binary() |
560 string() |
561 #sctp_sndrcvinfo{} |
562 #sctp_assoc_change{} |
563 #sctp_paddr_change{} |
564 #sctp_adaptation_event{}
565 Reason =
566 inet:posix() |
567 #sctp_send_failed{} |
568 #sctp_paddr_change{} |
569 #sctp_pdapi_event{} |
570 #sctp_remote_error{} |
571 #sctp_shutdown_event{}
572
573 Receives the Data message from any association of the socket. If
574 the receive times out, {error,timeout} is returned. The default
575 time-out is infinity. FromIP and FromPort indicate the address
576 of the sender.
577
578 AncData is a list of ancillary data items that can be received
579 along with the main Data. This list can be empty, or contain a
580 single #sctp_sndrcvinfo{} record if receiving of such ancillary
581 data is enabled (see option sctp_events). It is enabled by de‐
582 fault, as such ancillary data provides an easy way of determin‐
583 ing the association and stream over which the message is re‐
584 ceived. (An alternative way is to get the association ID from
585 FromIP and FromPort using socket option sctp_get_peer_addr_info,
586 but this does still not produce the stream number).
587
588 AncData may also contain ancillary data from the socket op‐
589 tions recvtos, recvtclass or recvttl, if that is supported by
590 the platform for the socket.
591
592 The Data received can be a binary() or a list() of bytes (inte‐
593 gers in the range 0 through 255) depending on the socket mode,
594 or an SCTP event.
595
596 Possible SCTP events:
597
598 * #sctp_sndrcvinfo{}
599
600 * #sctp_assoc_change{}
601
602 *
603
604
605 #sctp_paddr_change{
606 addr = {ip_address(),port()},
607 state = atom(),
608 error = integer(),
609 assoc_id = assoc_id()
610 }
611
612 Indicates change of the status of the IP address of the peer
613 specified by addr within association assoc_id. Possible val‐
614 ues of state (mostly self-explanatory) include:
615
616 addr_unreachable:
617
618
619 addr_available:
620
621
622 addr_removed:
623
624
625 addr_added:
626
627
628 addr_made_prim:
629
630
631 addr_confirmed:
632
633
634 In case of an error (for example, addr_unreachable), field
635 error provides more diagnostics. In such cases, event
636 #sctp_paddr_change{} is automatically converted into an er‐
637 ror term returned by recv. The error field value can be con‐
638 verted into a string using error_string/1.
639
640 *
641
642
643 #sctp_send_failed{
644 flags = true | false,
645 error = integer(),
646 info = #sctp_sndrcvinfo{},
647 assoc_id = assoc_id()
648 data = binary()
649 }
650
651 The sender can receive this event if a send operation fails.
652
653 flags:
654 A Boolean specifying if the data has been transmitted over
655 the wire.
656
657 error:
658 Provides extended diagnostics, use error_string/1.
659
660 info:
661 The original #sctp_sndrcvinfo{} record used in the failed
662 send/*.
663
664 data:
665 The whole original data chunk attempted to be sent.
666
667 In the current implementation of the Erlang/SCTP binding,
668 this event is internally converted into an error term re‐
669 turned by recv/*.
670
671 *
672
673
674 #sctp_adaptation_event{
675 adaptation_ind = integer(),
676 assoc_id = assoc_id()
677 }
678
679 Delivered when a peer sends an adaptation layer indication
680 parameter (configured through option sctp_adaptation_layer).
681 Notice that with the current implementation of the Er‐
682 lang/SCTP binding, this event is disabled by default.
683
684 *
685
686
687 #sctp_pdapi_event{
688 indication = sctp_partial_delivery_aborted,
689 assoc_id = assoc_id()
690 }
691
692 A partial delivery failure. In the current implementation of
693 the Erlang/SCTP binding, this event is internally converted
694 into an error term returned by recv/*.
695
696 send(Socket, SndRcvInfo, Data) -> ok | {error, Reason}
697
698 Types:
699
700 Socket = sctp_socket()
701 SndRcvInfo = #sctp_sndrcvinfo{}
702 Data = binary() | iolist()
703 Reason = term()
704
705 Sends the Data message with all sending parameters from a
706 #sctp_sndrcvinfo{} record. This way, the user can specify the
707 PPID (passed to the remote end) and context (passed to the local
708 SCTP layer), which can be used, for example, for error identifi‐
709 cation. However, such a fine level of user control is rarely re‐
710 quired. The function send/4 is sufficient for most applications.
711
712 send(Socket, Assoc, Stream, Data) -> ok | {error, Reason}
713
714 Types:
715
716 Socket = sctp_socket()
717 Assoc = #sctp_assoc_change{} | assoc_id()
718 Stream = integer()
719 Data = binary() | iolist()
720 Reason = term()
721
722 Sends a Data message over an existing association and specified
723 stream.
724
726 The set of admissible SCTP socket options is by construction orthogonal
727 to the sets of TCP, UDP, and generic inet options. Only options listed
728 here are allowed for SCTP sockets. Options can be set on the socket us‐
729 ing open/1,2 or inet:setopts/2, retrieved using inet:getopts/2. Options
730 can be changed when calling connect/4,5.
731
732 {mode, list|binary} or just list or binary:
733 Determines the type of data returned from recv/1,2.
734
735 {active, true|false|once|N}:
736
737
738 * If false (passive mode, the default), the caller must do an ex‐
739 plicit recv call to retrieve the available data from the socket.
740
741 * If true|once|N (active modes) received data or events are sent to
742 the owning process. See open/0..2 for the message format.
743
744 * If true (full active mode) there is no flow control.
745
746 Note:
747 Note that this can cause the message queue to overflow causing for
748 example the virtual machine to run out of memory and crash.
749
750
751 * If once, only one message is automatically placed in the message
752 queue, and after that the mode is automatically reset to passive.
753 This provides flow control and the possibility for the receiver
754 to listen for its incoming SCTP data interleaved with other in‐
755 ter-process messages.
756
757 * If active is specified as an integer N in the range -32768 to
758 32767 (inclusive), that number is added to the socket's counting
759 of data messages to be delivered to the controlling process. If
760 the result of the addition is negative, the count is set to 0.
761 Once the count reaches 0, either through the delivery of messages
762 or by being explicitly set with inet:setopts/2, the socket mode
763 is automatically reset to passive ({active, false}). When a
764 socket in this active mode transitions to passive mode, the mes‐
765 sage {sctp_passive, Socket} is sent to the controlling process to
766 notify it that if it wants to receive more data messages from the
767 socket, it must call inet:setopts/2 to set the socket back into
768 an active mode.
769
770 {tos, integer()}:
771 Sets the Type-Of-Service field on the IP datagrams that are sent,
772 to the specified value. This effectively determines a prioritiza‐
773 tion policy for the outbound packets. The acceptable values are
774 system-dependent.
775
776 {priority, integer()}:
777 A protocol-independent equivalent of tos above. Setting priority
778 implies setting tos as well.
779
780 {dontroute, true|false}:
781 Defaults to false. If true, the kernel does not send packets
782 through any gateway, only sends them to directly connected hosts.
783
784 {reuseaddr, true|false}:
785 Defaults to false. If true, the local binding address {IP,Port} of
786 the socket can be reused immediately. No waiting in state
787 CLOSE_WAIT is performed (can be required for high-throughput
788 servers).
789
790 {sndbuf, integer()}:
791 The size, in bytes, of the OS kernel send buffer for this socket.
792 Sending errors would occur for datagrams larger than val(sndbuf).
793 Setting this option also adjusts the size of the driver buffer (see
794 buffer above).
795
796 {recbuf, integer()}:
797 The size, in bytes, of the OS kernel receive buffer for this
798 socket. Sending errors would occur for datagrams larger than
799 val(recbuf). Setting this option also adjusts the size of the
800 driver buffer (see buffer above).
801
802 {sctp_module, module()}:
803 Overrides which callback module is used. Defaults to inet_sctp for
804 IPv4 and inet6_sctp for IPv6.
805
806 {sctp_rtoinfo, #sctp_rtoinfo{}}:
807
808
809 #sctp_rtoinfo{
810 assoc_id = assoc_id(),
811 initial = integer(),
812 max = integer(),
813 min = integer()
814 }
815
816 Determines retransmission time-out parameters, in milliseconds, for
817 the association(s) specified by assoc_id.
818
819 assoc_id = 0 (default) indicates the whole endpoint. See RFC 2960
820 and Sockets API Extensions for SCTP for the exact semantics of the
821 field values.
822
823 {sctp_associnfo, #sctp_assocparams{}}:
824
825
826 #sctp_assocparams{
827 assoc_id = assoc_id(),
828 asocmaxrxt = integer(),
829 number_peer_destinations = integer(),
830 peer_rwnd = integer(),
831 local_rwnd = integer(),
832 cookie_life = integer()
833 }
834
835 Determines association parameters for the association(s) specified
836 by assoc_id.
837
838 assoc_id = 0 (default) indicates the whole endpoint. See Sockets
839 API Extensions for SCTP for the discussion of their semantics.
840 Rarely used.
841
842 {sctp_initmsg, #sctp_initmsg{}}:
843
844
845 #sctp_initmsg{
846 num_ostreams = integer(),
847 max_instreams = integer(),
848 max_attempts = integer(),
849 max_init_timeo = integer()
850 }
851
852 Determines the default parameters that this socket tries to negoti‐
853 ate with its peer while establishing an association with it. Is to
854 be set after open/* but before the first connect/*. #sctp_initmsg{}
855 can also be used as ancillary data with the first call of send/* to
856 a new peer (when a new association is created).
857
858 num_ostreams:
859 Number of outbound streams
860
861 max_instreams:
862 Maximum number of inbound streams
863
864 max_attempts:
865 Maximum retransmissions while establishing an association
866
867 max_init_timeo:
868 Time-out, in milliseconds, for establishing an association
869
870 {sctp_autoclose, integer() >= 0}:
871 Determines the time, in seconds, after which an idle association is
872 automatically closed. 0 means that the association is never auto‐
873 matically closed.
874
875 {sctp_nodelay, true|false}:
876 Turns on|off the Nagle algorithm for merging small packets into
877 larger ones. This improves throughput at the expense of latency.
878
879 {sctp_disable_fragments, true|false}:
880 If true, induces an error on an attempt to send a message larger
881 than the current PMTU size (which would require fragmentation/re‐
882 assembling). Notice that message fragmentation does not affect the
883 logical atomicity of its delivery; this option is provided for per‐
884 formance reasons only.
885
886 {sctp_i_want_mapped_v4_addr, true|false}:
887 Turns on|off automatic mapping of IPv4 addresses into IPv6 ones (if
888 the socket address family is AF_INET6).
889
890 {sctp_maxseg, integer()}:
891 Determines the maximum chunk size if message fragmentation is used.
892 If 0, the chunk size is limited by the Path MTU only.
893
894 {sctp_primary_addr, #sctp_prim{}}:
895
896
897 #sctp_prim{
898 assoc_id = assoc_id(),
899 addr = {IP, Port}
900 }
901 IP = ip_address()
902 Port = port_number()
903
904 For the association specified by assoc_id, {IP,Port} must be one of
905 the peer addresses. This option determines that the specified ad‐
906 dress is treated by the local SCTP stack as the primary address of
907 the peer.
908
909 {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}:
910
911
912 #sctp_setpeerprim{
913 assoc_id = assoc_id(),
914 addr = {IP, Port}
915 }
916 IP = ip_address()
917 Port = port_number()
918
919 When set, informs the peer to use {IP, Port} as the primary address
920 of the local endpoint for the association specified by assoc_id.
921
922 {sctp_adaptation_layer, #sctp_setadaptation{}}:
923
924
925 #sctp_setadaptation{
926 adaptation_ind = integer()
927 }
928
929 When set, requests that the local endpoint uses the value specified
930 by adaptation_ind as the Adaptation Indication parameter for estab‐
931 lishing new associations. For details, see RFC 2960 and Sockets API
932 Extensions for SCTP.
933
934 {sctp_peer_addr_params, #sctp_paddrparams{}}:
935
936
937 #sctp_paddrparams{
938 assoc_id = assoc_id(),
939 address = {IP, Port},
940 hbinterval = integer(),
941 pathmaxrxt = integer(),
942 pathmtu = integer(),
943 sackdelay = integer(),
944 flags = list()
945 }
946 IP = ip_address()
947 Port = port_number()
948
949 Determines various per-address parameters for the association spec‐
950 ified by assoc_id and the peer address address (the SCTP protocol
951 supports multi-homing, so more than one address can correspond to a
952 specified association).
953
954 hbinterval:
955 Heartbeat interval, in milliseconds
956
957 pathmaxrxt:
958 Maximum number of retransmissions before this address is consid‐
959 ered unreachable (and an alternative address is selected)
960
961 pathmtu:
962 Fixed Path MTU, if automatic discovery is disabled (see flags be‐
963 low)
964
965 sackdelay:
966 Delay, in milliseconds, for SAC messages (if the delay is en‐
967 abled, see flags below)
968
969 flags:
970 The following flags are available:
971
972 hb_enable:
973 Enables heartbeat
974
975 hb_disable:
976 Disables heartbeat
977
978 hb_demand:
979 Initiates heartbeat immediately
980
981 pmtud_enable:
982 Enables automatic Path MTU discovery
983
984 pmtud_disable:
985 Disables automatic Path MTU discovery
986
987 sackdelay_enable:
988 Enables SAC delay
989
990 sackdelay_disable:
991 Disables SAC delay
992
993 {sctp_default_send_param, #sctp_sndrcvinfo{}}:
994
995
996 #sctp_sndrcvinfo{
997 stream = integer(),
998 ssn = integer(),
999 flags = list(),
1000 ppid = integer(),
1001 context = integer(),
1002 timetolive = integer(),
1003 tsn = integer(),
1004 cumtsn = integer(),
1005 assoc_id = assoc_id()
1006 }
1007
1008 #sctp_sndrcvinfo{} is used both in this socket option, and as an‐
1009 cillary data while sending or receiving SCTP messages. When set as
1010 an option, it provides default values for subsequent send calls on
1011 the association specified by assoc_id.
1012
1013 assoc_id = 0 (default) indicates the whole endpoint.
1014
1015 The following fields typically must be specified by the sender:
1016
1017 sinfo_stream:
1018 Stream number (0-base) within the association to send the mes‐
1019 sages through;
1020
1021 sinfo_flags:
1022 The following flags are recognised:
1023
1024 unordered:
1025 The message is to be sent unordered
1026
1027 addr_over:
1028 The address specified in send overwrites the primary peer ad‐
1029 dress
1030
1031 abort:
1032 Aborts the current association without flushing any unsent data
1033
1034 eof:
1035 Gracefully shuts down the current association, with flushing of
1036 unsent data
1037
1038 Other fields are rarely used. For complete information, see RFC
1039 2960 and Sockets API Extensions for SCTP.
1040
1041 {sctp_events, #sctp_event_subscribe{}}:
1042
1043
1044 #sctp_event_subscribe{
1045 data_io_event = true | false,
1046 association_event = true | false,
1047 address_event = true | false,
1048 send_failure_event = true | false,
1049 peer_error_event = true | false,
1050 shutdown_event = true | false,
1051 partial_delivery_event = true | false,
1052 adaptation_layer_event = true | false
1053 }
1054
1055 This option determines which SCTP Events are to be received
1056 (through recv/*) along with the data. The only exception is
1057 data_io_event, which enables or disables receiving of #sctp_sndrcv‐
1058 info{} ancillary data, not events. By default, all flags except
1059 adaptation_layer_event are enabled, although sctp_data_io_event and
1060 association_event are used by the driver itself and not exported to
1061 the user level.
1062
1063 {sctp_delayed_ack_time, #sctp_assoc_value{}}:
1064
1065
1066 #sctp_assoc_value{
1067 assoc_id = assoc_id(),
1068 assoc_value = integer()
1069 }
1070
1071 Rarely used. Determines the ACK time (specified by assoc_value, in
1072 milliseconds) for the specified association or the whole endpoint
1073 if assoc_value = 0 (default).
1074
1075 {sctp_status, #sctp_status{}}:
1076
1077
1078 #sctp_status{
1079 assoc_id = assoc_id(),
1080 state = atom(),
1081 rwnd = integer(),
1082 unackdata = integer(),
1083 penddata = integer(),
1084 instrms = integer(),
1085 outstrms = integer(),
1086 fragmentation_point = integer(),
1087 primary = #sctp_paddrinfo{}
1088 }
1089
1090 This option is read-only. It determines the status of the SCTP as‐
1091 sociation specified by assoc_id. The following are the possible
1092 values of state (the state designations are mostly self-explana‐
1093 tory):
1094
1095 sctp_state_empty:
1096 Default. Means that no other state is active.
1097
1098 sctp_state_closed:
1099
1100
1101 sctp_state_cookie_wait:
1102
1103
1104 sctp_state_cookie_echoed:
1105
1106
1107 sctp_state_established:
1108
1109
1110 sctp_state_shutdown_pending:
1111
1112
1113 sctp_state_shutdown_sent:
1114
1115
1116 sctp_state_shutdown_received:
1117
1118
1119 sctp_state_shutdown_ack_sent:
1120
1121
1122 Semantics of the other fields:
1123
1124 sstat_rwnd:
1125 Current receiver window size of the association
1126
1127 sstat_unackdata:
1128 Number of unacked data chunks
1129
1130 sstat_penddata:
1131 Number of data chunks pending receipt
1132
1133 sstat_instrms:
1134 Number of inbound streams
1135
1136 sstat_outstrms:
1137 Number of outbound streams
1138
1139 sstat_fragmentation_point:
1140 Message size at which SCTP fragmentation occurs
1141
1142 sstat_primary:
1143 Information on the current primary peer address (see below for
1144 the format of #sctp_paddrinfo{})
1145
1146 {sctp_get_peer_addr_info, #sctp_paddrinfo{}}:
1147
1148
1149 #sctp_paddrinfo{
1150 assoc_id = assoc_id(),
1151 address = {IP, Port},
1152 state = inactive | active | unconfirmed,
1153 cwnd = integer(),
1154 srtt = integer(),
1155 rto = integer(),
1156 mtu = integer()
1157 }
1158 IP = ip_address()
1159 Port = port_number()
1160
1161 This option is read-only. It determines the parameters specific to
1162 the peer address specified by address within the association speci‐
1163 fied by assoc_id. Field address fmust be set by the caller; all
1164 other fields are filled in on return. If assoc_id = 0 (default),
1165 the address is automatically translated into the corresponding as‐
1166 sociation ID. This option is rarely used. For the semantics of all
1167 fields, see RFC 2960 and Sockets API Extensions for SCTP.
1168
1170 Example of an Erlang SCTP server that receives SCTP messages and prints
1171 them on the standard output:
1172
1173 -module(sctp_server).
1174
1175 -export([server/0,server/1,server/2]).
1176 -include_lib("kernel/include/inet.hrl").
1177 -include_lib("kernel/include/inet_sctp.hrl").
1178
1179 server() ->
1180 server(any, 2006).
1181
1182 server([Host,Port]) when is_list(Host), is_list(Port) ->
1183 {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
1184 io:format("~w -> ~w~n", [Host, IP]),
1185 server([IP, list_to_integer(Port)]).
1186
1187 server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
1188 is_integer(Port) ->
1189 {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
1190 io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
1191 ok = gen_sctp:listen(S, true),
1192 server_loop(S).
1193
1194 server_loop(S) ->
1195 case gen_sctp:recv(S) of
1196 {error, Error} ->
1197 io:format("SCTP RECV ERROR: ~p~n", [Error]);
1198 Data ->
1199 io:format("Received: ~p~n", [Data])
1200 end,
1201 server_loop(S).
1202
1203 Example of an Erlang SCTP client interacting with the above server. No‐
1204 tice that in this example the client creates an association with the
1205 server with 5 outbound streams. Therefore, sending of "Test 0" over
1206 stream 0 succeeds, but sending of "Test 5" over stream 5 fails. The
1207 client then aborts the association, which results in that the corre‐
1208 sponding event is received on the server side.
1209
1210 -module(sctp_client).
1211
1212 -export([client/0, client/1, client/2]).
1213 -include_lib("kernel/include/inet.hrl").
1214 -include_lib("kernel/include/inet_sctp.hrl").
1215
1216 client() ->
1217 client([localhost]).
1218
1219 client([Host]) ->
1220 client(Host, 2006);
1221
1222 client([Host, Port]) when is_list(Host), is_list(Port) ->
1223 client(Host,list_to_integer(Port)),
1224 init:stop().
1225
1226 client(Host, Port) when is_integer(Port) ->
1227 {ok,S} = gen_sctp:open(),
1228 {ok,Assoc} = gen_sctp:connect
1229 (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
1230 io:format("Connection Successful, Assoc=~p~n", [Assoc]),
1231
1232 io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
1233 io:nl(),
1234 timer:sleep(10000),
1235 io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
1236 io:nl(),
1237 timer:sleep(10000),
1238 io:write(gen_sctp:abort(S, Assoc)),
1239 io:nl(),
1240
1241 timer:sleep(1000),
1242 gen_sctp:close(S).
1243
1244 A simple Erlang SCTP client that uses the connect_init API:
1245
1246 -module(ex3).
1247
1248 -export([client/4]).
1249 -include_lib("kernel/include/inet.hrl").
1250 -include_lib("kernel/include/inet_sctp.hrl").
1251
1252 client(Peer1, Port1, Peer2, Port2)
1253 when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
1254 {ok,S} = gen_sctp:open(),
1255 SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
1256 ActiveOpt = {active, true},
1257 Opts = [SctpInitMsgOpt, ActiveOpt],
1258 ok = gen_sctp:connect(S, Peer1, Port1, Opts),
1259 ok = gen_sctp:connect(S, Peer2, Port2, Opts),
1260 io:format("Connections initiated~n", []),
1261 client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).
1262
1263 client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
1264 receive
1265 {sctp, S, Peer1, Port1, {_Anc, SAC}}
1266 when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
1267 io:format("Association 1 connect result: ~p. AssocId: ~p~n",
1268 [SAC#sctp_assoc_change.state,
1269 SAC#sctp_assoc_change.assoc_id]),
1270 client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
1271 Peer2, Port2, AssocId2);
1272
1273 {sctp, S, Peer2, Port2, {_Anc, SAC}}
1274 when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
1275 io:format("Association 2 connect result: ~p. AssocId: ~p~n",
1276 [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
1277 client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
1278 SAC#sctp_assoc_change.assoc_id);
1279
1280 {sctp, S, Peer1, Port1, Data} ->
1281 io:format("Association 1: received ~p~n", [Data]),
1282 client_loop(S, Peer1, Port1, AssocId1,
1283 Peer2, Port2, AssocId2);
1284
1285 {sctp, S, Peer2, Port2, Data} ->
1286 io:format("Association 2: received ~p~n", [Data]),
1287 client_loop(S, Peer1, Port1, AssocId1,
1288 Peer2, Port2, AssocId2);
1289
1290 Other ->
1291 io:format("Other ~p~n", [Other]),
1292 client_loop(S, Peer1, Port1, AssocId1,
1293 Peer2, Port2, AssocId2)
1294
1295 after 5000 ->
1296 ok
1297 end.
1298
1300 gen_tcp(3), gen_udp(3), inet(3), RFC 2960 (Stream Control Transmission
1301 Protocol), Sockets API Extensions for SCTP
1302
1303
1304
1305Ericsson AB kernel 8.5.3 gen_sctp(3)