sctp-socket 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f9f0ecd09038bfc074d38f36b387c26a5f203c3d57ae5d6ad7f5b2c085e945f
4
- data.tar.gz: 563a9e79224c46e71872de30a59a17ece441113dcab2cc8d4e153a7a89313b97
3
+ metadata.gz: 020ddee983f419ae152f2380b8275e61f66e70721f253eb33b65968a2bd82ef6
4
+ data.tar.gz: 7b9aa313541d38d4e1656813f00c2efcc4d5d61d1dcd1888706757e8e6c3ca8f
5
5
  SHA512:
6
- metadata.gz: 714abd0b5f6ecb95778ddf81d03dbfc6d23f1bfcfdebe62d4bed25cf3aaecc869e1235f6e5c04a5de123b0022ed9b6bdcb39d13a340d0aae3f3e50340c10ad26
7
- data.tar.gz: c88bcdc5f0f456e4ef3a75f9c06f52ba60600959bfe7d654d398dfe0a3c8f9a19d76ee4d577c119a0b367c525b6395172a86ff6e6259fff8e697b345e122f616
6
+ metadata.gz: 8db4f1600b5afe84c5930eb2e3953a1eb71353ba53f6fbf6637661cd8266ac7bf208528e7809f55110ae16ef3bb09412fca6bc5ce317c161ecaed9c11697fc74
7
+ data.tar.gz: 46d38b4f47252e7df76557215d430a21b94009270ab6e9e09e0d08e8bc34d990ded3e059a4bd5b661d52c01bcc7a5743242a6e9d3ec5cbbdf3b29ff56e9ff350
checksums.yaml.gz.sig CHANGED
Binary file
data/.gitignore CHANGED
@@ -5,3 +5,4 @@
5
5
  Makefile
6
6
  tmp/
7
7
  .vscode
8
+ *.bundle
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.3.0 - 8-Feb-2026
2
+ * Add a compatability layer for libusrsctp. This was mainly for MacOS, but
3
+ it should work on any platform.
4
+
1
5
  ## 0.2.2 - 7-Jan-2026
2
6
  * Added IPv6 support.
3
7
  * Some internal refactoring and updates, potential memory leak fixes, etc.
data/MANIFEST.md CHANGED
@@ -1,12 +1,49 @@
1
1
  * CHANGES.md
2
2
  * certs/djberg96_pub.pem
3
3
  * examples/client_example.rb
4
+ * examples/client_for_server_test.rb
5
+ * examples/sctp_server_example.rb
4
6
  * examples/server_example.rb
7
+ * examples/server_using_sctp_server.rb
8
+ * ext/sctp/extconf.rb
9
+ * ext/sctp/sctp_compat.h
5
10
  * ext/sctp/socket.c
6
- * ext/sctp/socket.h
7
11
  * Gemfile
12
+ * lib/sctp/server.rb
8
13
  * LICENSE
14
+ * MANIFEST.md
9
15
  * Rakefile
10
16
  * README.md
11
17
  * sctp-socket.gemspec
12
- * spec/sctp_spec.rb
18
+ * spec/active_shared_key_spec.rb
19
+ * spec/auth_support_spec.rb
20
+ * spec/autoclose_spec.rb
21
+ * spec/bindx_spec.rb
22
+ * spec/close_spec.rb
23
+ * spec/connectx_spec.rb
24
+ * spec/constants_spec.rb
25
+ * spec/constructor_spec.rb
26
+ * spec/get_default_send_params_spec.rb
27
+ * spec/get_init_msg_spec.rb
28
+ * spec/get_peer_address_params_spec.rb
29
+ * spec/get_status_spec.rb
30
+ * spec/getlocalnames_spec.rb
31
+ * spec/getpeernames_spec.rb
32
+ * spec/listen_spec.rb
33
+ * spec/map_ipv4_spec.rb
34
+ * spec/nodelay_spec.rb
35
+ * spec/notification_spec.rb
36
+ * spec/recvmsg_spec.rb
37
+ * spec/recvv_spec.rb
38
+ * spec/retransmission_info_spec.rb
39
+ * spec/sctp_server_spec.rb
40
+ * spec/sendmsg_spec.rb
41
+ * spec/sendv_spec.rb
42
+ * spec/set_default_send_params_spec.rb
43
+ * spec/set_peer_address_params_spec.rb
44
+ * spec/shared_key_spec.rb
45
+ * spec/shared_spec_helper.rb
46
+ * spec/shutdown_spec.rb
47
+ * spec/spec_helper.rb
48
+ * spec/subscribe_spec.rb
49
+ * spec/version_spec.rb
data/Rakefile CHANGED
@@ -48,11 +48,9 @@ task :create_dummy_links do
48
48
  system('sudo ip link set dummy2 up')
49
49
  system('ip link show')
50
50
  else
51
- system("sudo ifconfig lo1 create")
52
- system("sudo ifconfig lo1 1.1.1.1/24 up")
53
- system("sudo ifconfig lo2 create")
54
- system("sudo ifconfig lo2 1.1.1.2/24 up")
55
- system("sudo ifconfig -a")
51
+ system("sudo ifconfig lo0 alias 1.1.1.1/24 up")
52
+ system("sudo ifconfig lo0 alias 1.1.1.2/24 up")
53
+ system("sudo ifconfig lo0")
56
54
  end
57
55
  end
58
56
 
data/ext/sctp/extconf.rb CHANGED
@@ -2,36 +2,45 @@ require 'mkmf'
2
2
 
3
3
  dir_config('sctp')
4
4
 
5
- unless have_header('netinet/sctp.h')
6
- os = IO.readlines('/etc/os-release').first.split('=').last
7
- msg = "\nSCTP HEADERS NOT FOUND. PLEASE INSTALL THEM FIRST LIKE SO:\n\n"
8
-
9
- if os =~ /red|fedora|centos/i
10
- msg << "#####################################################################################\n"
11
- msg << "# dnf install lksctp-tools #\n"
12
- msg << "# dnf install kernel-modules-extra #\n"
13
- msg << "# #\n"
14
- msg << "# sed -e '/blacklist sctp/s/^b/#b/g' -i /etc/modprobe.d/sctp-blacklist.conf #\n"
15
- msg << "# sed -e '/blacklist sctp/s/^b/#b/g' -i /etc/modprobe.d/sctp_diag-blacklist.conf #\n"
16
- msg << "# #\n"
17
- msg << "# sudo systemctl restart systemd-modules-load.service #\n"
18
- msg << "#####################################################################################\n"
19
- else
20
- msg << "sudo apt-get install libsctp-dev lksctp-tools\n\n"
5
+ if have_header('netinet/sctp.h')
6
+ # Native kernel SCTP (Linux, FreeBSD, etc.)
7
+ header = 'netinet/sctp.h'
8
+ have_library('sctp')
9
+ have_func('sctp_sendv', header)
10
+ have_func('sctp_recvv', header)
11
+ else
12
+ # Fall back to usrsctp (primarily for macOS)
13
+ if RUBY_PLATFORM =~ /darwin/
14
+ homebrew_prefix = ENV['HOMEBREW_PREFIX'] || '/opt/homebrew'
15
+
16
+ if File.directory?("#{homebrew_prefix}/include")
17
+ $CFLAGS << " -I#{homebrew_prefix}/include"
18
+ $LDFLAGS << " -L#{homebrew_prefix}/lib"
19
+ end
21
20
  end
22
21
 
23
- warn msg
24
- exit
25
- end
22
+ unless have_header('usrsctp.h')
23
+ abort <<~MSG
26
24
 
27
- header = 'netinet/sctp.h'
25
+ ERROR: Neither netinet/sctp.h nor usrsctp.h found.
28
26
 
29
- have_library('sctp')
27
+ On macOS: brew install libusrsctp
28
+ On Ubuntu: sudo apt-get install libsctp-dev lksctp-tools
29
+ On Fedora: dnf install lksctp-tools kernel-modules-extra
30
30
 
31
- have_header('sys/param.h')
31
+ MSG
32
+ end
33
+
34
+ header = 'usrsctp.h'
35
+ have_library('usrsctp')
32
36
 
33
- have_func('sctp_sendv', header)
34
- have_func('sctp_recvv', header)
37
+ # usrsctp always provides sendv/recvv (as usrsctp_sendv/usrsctp_recvv),
38
+ # so define the feature macros so those code paths compile in.
39
+ $defs << '-DHAVE_SCTP_SENDV=1'
40
+ $defs << '-DHAVE_SCTP_RECVV=1'
41
+ end
42
+
43
+ have_header('sys/param.h')
35
44
 
36
45
  have_struct_member('struct sctp_event_subscribe', 'sctp_send_failure_event', header)
37
46
  have_struct_member('struct sctp_event_subscribe', 'sctp_stream_reset_event', header)
@@ -0,0 +1,369 @@
1
+ /*
2
+ * sctp_compat.h - Compatibility layer for native kernel SCTP vs usrsctp.
3
+ *
4
+ * This header abstracts the API differences between the native Linux
5
+ * kernel SCTP stack (via netinet/sctp.h) and the userspace SCTP library
6
+ * (usrsctp) so the same C code can work with both backends.
7
+ *
8
+ * Key differences handled:
9
+ * - Socket descriptor type: int (native) vs struct socket* (usrsctp)
10
+ * - Ruby VALUE conversion: INT2NUM/NUM2INT vs LONG2NUM/NUM2LONG (64-bit safe)
11
+ * - All sctp_* and POSIX socket calls mapped to sctp_sys_* wrappers
12
+ * - Scatter/gather (iov) vs flat buffer (usrsctp_sendv/recvv)
13
+ * - sctp_sendmsg/sctp_sendmsgx unified into sctp_sys_sendmsg
14
+ * - sctp_recvmsg wrapped to use usrsctp_recvv
15
+ */
16
+ #ifndef SCTP_COMPAT_H
17
+ #define SCTP_COMPAT_H
18
+
19
+ #ifdef HAVE_USRSCTP_H
20
+
21
+ /* =========================================================================
22
+ * usrsctp backend (primarily for macOS)
23
+ * ========================================================================= */
24
+
25
+ #include <usrsctp.h>
26
+
27
+ /*
28
+ * usrsctp removed the deprecated sctp_sndrcvinfo struct; provide a compat
29
+ * definition so the rest of the code can use a single struct throughout.
30
+ * The sctp_sys_send / sctp_sys_recvmsg wrappers translate between this
31
+ * struct and the usrsctp-native sctp_sndinfo / sctp_rcvinfo.
32
+ */
33
+ struct sctp_sndrcvinfo {
34
+ uint16_t sinfo_stream;
35
+ uint16_t sinfo_ssn;
36
+ uint16_t sinfo_flags;
37
+ uint32_t sinfo_ppid;
38
+ uint32_t sinfo_context;
39
+ uint32_t sinfo_timetolive;
40
+ uint32_t sinfo_tsn;
41
+ uint32_t sinfo_cumtsn;
42
+ sctp_assoc_t sinfo_assoc_id;
43
+ };
44
+
45
+ /*
46
+ * usrsctp removed the deprecated SCTP_DEFAULT_SEND_PARAM sockopt (0x0b).
47
+ * We define a compat constant that our wrappers will translate into the
48
+ * appropriate SCTP_DEFAULT_SNDINFO call. The value must not collide with
49
+ * any real usrsctp sockopt, so pick something far away.
50
+ */
51
+ #define SCTP_DEFAULT_SEND_PARAM 0xF00D
52
+
53
+ /*
54
+ * Socket descriptor type: struct socket* for usrsctp
55
+ */
56
+ typedef struct socket* sctp_sock_t;
57
+
58
+ /* Convert between Ruby VALUE and socket descriptor (64-bit pointer safe) */
59
+ #define SCTP_FD_TO_NUM(fd) LONG2NUM((intptr_t)(fd))
60
+ #define NUM_TO_SCTP_FD(v) ((sctp_sock_t)(uintptr_t)NUM2LONG(v))
61
+ #define SCTP_FD_INVALID(fd) ((fd) == NULL)
62
+
63
+ /* --- Global usrsctp lifecycle --- */
64
+
65
+ static int _usrsctp_initialized = 0;
66
+
67
+ static inline void sctp_sys_global_init(void){
68
+ if(!_usrsctp_initialized){
69
+ usrsctp_init(0, NULL, NULL);
70
+ _usrsctp_initialized = 1;
71
+ }
72
+ }
73
+
74
+ /* --- Socket operations --- */
75
+
76
+ static inline sctp_sock_t sctp_sys_socket(int domain, int type, int protocol){
77
+ sctp_sys_global_init();
78
+ return usrsctp_socket(domain, type, protocol, NULL, NULL, 0, NULL);
79
+ }
80
+
81
+ /* usrsctp_close returns void, wrap to return int for uniform error handling */
82
+ static inline int sctp_sys_close(sctp_sock_t fd){
83
+ usrsctp_close(fd);
84
+ return 0;
85
+ }
86
+
87
+ #define sctp_sys_listen(fd, bl) usrsctp_listen(fd, bl)
88
+ #define sctp_sys_shutdown(fd, h) usrsctp_shutdown(fd, h)
89
+
90
+ /* --- Socket options --- */
91
+
92
+ #define sctp_sys_setsockopt(fd, level, name, val, len) \
93
+ usrsctp_setsockopt(fd, level, name, val, len)
94
+ #define sctp_sys_getsockopt(fd, level, name, val, len) \
95
+ usrsctp_getsockopt(fd, level, name, val, len)
96
+
97
+ /* --- SCTP-specific operations (1:1 mappings) --- */
98
+
99
+ #define sctp_sys_bindx(fd, addrs, num, flags) usrsctp_bindx(fd, addrs, num, flags)
100
+ #define sctp_sys_connectx(fd, addrs, num, assoc) usrsctp_connectx(fd, addrs, num, assoc)
101
+ #define sctp_sys_peeloff(fd, assoc) usrsctp_peeloff(fd, assoc)
102
+ #define sctp_sys_getpaddrs(fd, assoc, addrs) usrsctp_getpaddrs(fd, assoc, addrs)
103
+ #define sctp_sys_getladdrs(fd, assoc, addrs) usrsctp_getladdrs(fd, assoc, addrs)
104
+ #define sctp_sys_freepaddrs(addrs) usrsctp_freepaddrs(addrs)
105
+ #define sctp_sys_freeladdrs(addrs) usrsctp_freeladdrs(addrs)
106
+ #define sctp_sys_opt_info(fd, assoc, opt, arg, sz) usrsctp_opt_info(fd, assoc, opt, arg, sz)
107
+
108
+ /* --- sendv wrapper ---
109
+ * Native sctp_sendv uses iov+iovlen; usrsctp_sendv uses buf+len.
110
+ * This wrapper concatenates iov entries if needed.
111
+ *
112
+ * usrsctp_sendv only supports a single destination address (addrcnt<=1),
113
+ * so we cap addrcnt at 1. This is not a practical limitation: SCTP's
114
+ * multihoming addresses are exchanged during association setup (INIT/INIT-ACK)
115
+ * and the stack already knows every peer address. When sending data the
116
+ * address parameter only selects which path to use for that message (or NULL
117
+ * for the primary path), so more than one address is never meaningful.
118
+ */
119
+ static inline ssize_t sctp_sys_sendv(sctp_sock_t fd, const struct iovec* iov, int iovcnt,
120
+ struct sockaddr* addrs, int addrcnt, void* info, socklen_t infolen,
121
+ unsigned int infotype, int flags)
122
+ {
123
+ if(addrcnt > 1)
124
+ addrcnt = 1;
125
+
126
+ if(iovcnt == 1){
127
+ return usrsctp_sendv(fd, iov[0].iov_base, iov[0].iov_len,
128
+ addrs, addrcnt, info, infolen, infotype, flags);
129
+ }
130
+
131
+ /* Multiple iov entries: concatenate into a single buffer */
132
+ size_t total = 0;
133
+ int i;
134
+ ssize_t result;
135
+ char* buf;
136
+
137
+ for(i = 0; i < iovcnt; i++)
138
+ total += iov[i].iov_len;
139
+
140
+ buf = (char*)malloc(total);
141
+
142
+ if(!buf){
143
+ errno = ENOMEM;
144
+ return -1;
145
+ }
146
+
147
+ {
148
+ size_t offset = 0;
149
+ for(i = 0; i < iovcnt; i++){
150
+ memcpy(buf + offset, iov[i].iov_base, iov[i].iov_len);
151
+ offset += iov[i].iov_len;
152
+ }
153
+ }
154
+
155
+ result = usrsctp_sendv(fd, buf, total,
156
+ addrs, addrcnt, info, infolen, infotype, flags);
157
+ free(buf);
158
+ return result;
159
+ }
160
+
161
+ /* --- recvv wrapper ---
162
+ * Native sctp_recvv uses iov; usrsctp_recvv uses buf+len.
163
+ * Assumes iovcnt == 1 (which is how this library uses it).
164
+ */
165
+ static inline ssize_t sctp_sys_recvv(sctp_sock_t fd, const struct iovec* iov, int iovcnt,
166
+ struct sockaddr* from, socklen_t* fromlen,
167
+ void* info, socklen_t* infolen, unsigned int* infotype, int* flags)
168
+ {
169
+ (void)iovcnt;
170
+ return usrsctp_recvv(fd, iov[0].iov_base, iov[0].iov_len,
171
+ from, fromlen, info, infolen, infotype, flags);
172
+ }
173
+
174
+ /* --- getsockname wrapper ---
175
+ * usrsctp doesn't have getsockname(); use usrsctp_getladdrs() instead.
176
+ */
177
+ static inline int sctp_sys_getsockname(sctp_sock_t fd, struct sockaddr* addr, socklen_t* addrlen){
178
+ struct sockaddr* addrs = NULL;
179
+ int n = usrsctp_getladdrs(fd, 0, &addrs);
180
+ socklen_t copy_len;
181
+
182
+ if(n <= 0)
183
+ return -1;
184
+
185
+ if(addrs->sa_family == AF_INET6)
186
+ copy_len = sizeof(struct sockaddr_in6);
187
+ else
188
+ copy_len = sizeof(struct sockaddr_in);
189
+
190
+ if(copy_len > *addrlen)
191
+ copy_len = *addrlen;
192
+
193
+ memcpy(addr, addrs, copy_len);
194
+ *addrlen = copy_len;
195
+ usrsctp_freeladdrs(addrs);
196
+
197
+ return 0;
198
+ }
199
+
200
+ /* --- sctp_send wrapper ---
201
+ * usrsctp doesn't have sctp_send(); map to usrsctp_sendv with SCTP_SENDV_SNDINFO.
202
+ */
203
+ static inline ssize_t sctp_sys_send(sctp_sock_t fd, const void* msg, size_t len,
204
+ const struct sctp_sndrcvinfo* sinfo, int flags)
205
+ {
206
+ struct sctp_sndinfo sndinfo;
207
+ memset(&sndinfo, 0, sizeof(sndinfo));
208
+
209
+ if(sinfo){
210
+ sndinfo.snd_sid = sinfo->sinfo_stream;
211
+ sndinfo.snd_flags = sinfo->sinfo_flags;
212
+ sndinfo.snd_ppid = sinfo->sinfo_ppid;
213
+ sndinfo.snd_context = sinfo->sinfo_context;
214
+ sndinfo.snd_assoc_id = sinfo->sinfo_assoc_id;
215
+ }
216
+
217
+ return usrsctp_sendv(fd, msg, len, NULL, 0,
218
+ &sndinfo, sizeof(sndinfo), SCTP_SENDV_SNDINFO, flags);
219
+ }
220
+
221
+ /* --- sctp_sendmsg wrapper ---
222
+ * Unified interface: takes addrcnt (count of addresses), not byte length.
223
+ * usrsctp doesn't have sctp_sendmsg(); map to usrsctp_sendv with SCTP_SENDV_SPA.
224
+ */
225
+ static inline ssize_t sctp_sys_sendmsg(sctp_sock_t fd, const void* msg, size_t len,
226
+ struct sockaddr* to, int addrcnt,
227
+ uint32_t ppid, uint32_t flags, uint16_t stream, uint32_t ttl, uint32_t context)
228
+ {
229
+ struct sctp_sendv_spa spa;
230
+ memset(&spa, 0, sizeof(spa));
231
+
232
+ spa.sendv_sndinfo.snd_sid = stream;
233
+ spa.sendv_sndinfo.snd_flags = flags;
234
+ spa.sendv_sndinfo.snd_ppid = ppid;
235
+ spa.sendv_sndinfo.snd_context = context;
236
+ spa.sendv_flags = SCTP_SEND_SNDINFO_VALID;
237
+
238
+ if(ttl > 0){
239
+ spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL;
240
+ spa.sendv_prinfo.pr_value = ttl;
241
+ spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
242
+ }
243
+
244
+ /*
245
+ * Cap to one destination address — see the comment on sctp_sys_sendv
246
+ * for why this is not a practical limitation.
247
+ */
248
+ if(addrcnt > 1)
249
+ addrcnt = 1;
250
+
251
+ return usrsctp_sendv(fd, msg, len, to, addrcnt,
252
+ &spa, sizeof(spa), SCTP_SENDV_SPA, 0);
253
+ }
254
+
255
+ /* --- sctp_recvmsg wrapper ---
256
+ * usrsctp doesn't have sctp_recvmsg(); map to usrsctp_recvv and translate
257
+ * the rcvinfo back into an sctp_sndrcvinfo structure.
258
+ */
259
+ static inline ssize_t sctp_sys_recvmsg(sctp_sock_t fd, void* buf, size_t len,
260
+ struct sockaddr* from, socklen_t* fromlen,
261
+ struct sctp_sndrcvinfo* sinfo, int* msg_flags)
262
+ {
263
+ struct sctp_rcvinfo rcvinfo;
264
+ socklen_t infolen = sizeof(rcvinfo);
265
+ unsigned int infotype = 0;
266
+ ssize_t n;
267
+
268
+ /* Ensure rcvinfo is returned */
269
+ int on = 1;
270
+ usrsctp_setsockopt(fd, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(on));
271
+
272
+ memset(&rcvinfo, 0, sizeof(rcvinfo));
273
+
274
+ n = usrsctp_recvv(fd, buf, len, from, fromlen,
275
+ &rcvinfo, &infolen, &infotype, msg_flags);
276
+
277
+ if(n >= 0 && sinfo != NULL){
278
+ memset(sinfo, 0, sizeof(*sinfo));
279
+ if(infotype == SCTP_RECVV_RCVINFO){
280
+ sinfo->sinfo_stream = rcvinfo.rcv_sid;
281
+ sinfo->sinfo_ssn = rcvinfo.rcv_ssn;
282
+ sinfo->sinfo_flags = rcvinfo.rcv_flags;
283
+ sinfo->sinfo_ppid = rcvinfo.rcv_ppid;
284
+ sinfo->sinfo_tsn = rcvinfo.rcv_tsn;
285
+ sinfo->sinfo_cumtsn = rcvinfo.rcv_cumtsn;
286
+ sinfo->sinfo_context = rcvinfo.rcv_context;
287
+ sinfo->sinfo_assoc_id = rcvinfo.rcv_assoc_id;
288
+ }
289
+ }
290
+
291
+ return n;
292
+ }
293
+
294
+ #else
295
+
296
+ /* =========================================================================
297
+ * Native kernel SCTP backend (Linux, FreeBSD, etc.)
298
+ * ========================================================================= */
299
+
300
+ #include <netinet/sctp.h>
301
+
302
+ /*
303
+ * Socket descriptor type: int file descriptor for native SCTP
304
+ */
305
+ typedef int sctp_sock_t;
306
+
307
+ /* Convert between Ruby VALUE and socket descriptor */
308
+ #define SCTP_FD_TO_NUM(fd) INT2NUM(fd)
309
+ #define NUM_TO_SCTP_FD(v) NUM2INT(v)
310
+ #define SCTP_FD_INVALID(fd) ((fd) < 0)
311
+
312
+ /* No-op for native SCTP */
313
+ static inline void sctp_sys_global_init(void){}
314
+
315
+ /* --- Socket operations: direct pass-through --- */
316
+
317
+ #define sctp_sys_socket(domain, type, proto) socket(domain, type, proto)
318
+ #define sctp_sys_close(fd) close(fd)
319
+ #define sctp_sys_listen(fd, bl) listen(fd, bl)
320
+ #define sctp_sys_shutdown(fd, h) shutdown(fd, h)
321
+
322
+ /* --- Socket options --- */
323
+
324
+ #define sctp_sys_setsockopt setsockopt
325
+ #define sctp_sys_getsockopt getsockopt
326
+ #define sctp_sys_getsockname getsockname
327
+
328
+ /* --- SCTP operations: direct pass-through --- */
329
+
330
+ #define sctp_sys_bindx sctp_bindx
331
+ #define sctp_sys_connectx sctp_connectx
332
+ #define sctp_sys_peeloff sctp_peeloff
333
+ #define sctp_sys_getpaddrs sctp_getpaddrs
334
+ #define sctp_sys_getladdrs sctp_getladdrs
335
+ #define sctp_sys_freepaddrs sctp_freepaddrs
336
+ #define sctp_sys_freeladdrs sctp_freeladdrs
337
+ #define sctp_sys_opt_info sctp_opt_info
338
+ #define sctp_sys_sendv sctp_sendv
339
+ #define sctp_sys_recvv sctp_recvv
340
+ #define sctp_sys_send sctp_send
341
+ #define sctp_sys_recvmsg sctp_recvmsg
342
+
343
+ /* --- sctp_sendmsg wrapper ---
344
+ * Unified interface: always takes addrcnt (count), not byte length.
345
+ * On BSD, maps to sctp_sendmsgx (which takes count).
346
+ * On Linux, maps to sctp_sendmsg (which takes byte length), so we compute it.
347
+ */
348
+ static inline ssize_t sctp_sys_sendmsg(sctp_sock_t fd, const void* msg, size_t len,
349
+ struct sockaddr* to, int addrcnt,
350
+ uint32_t ppid, uint32_t flags, uint16_t stream, uint32_t ttl, uint32_t context)
351
+ {
352
+ #ifdef BSD
353
+ return sctp_sendmsgx(fd, msg, len, to, addrcnt, ppid, flags, stream, ttl, context);
354
+ #else
355
+ socklen_t tolen = 0;
356
+
357
+ if(to != NULL){
358
+ if(to->sa_family == AF_INET6)
359
+ tolen = addrcnt * sizeof(struct sockaddr_in6);
360
+ else
361
+ tolen = addrcnt * sizeof(struct sockaddr_in);
362
+ }
363
+
364
+ return sctp_sendmsg(fd, msg, len, to, tolen, ppid, flags, stream, ttl, context);
365
+ #endif
366
+ }
367
+
368
+ #endif /* HAVE_USRSCTP_H */
369
+ #endif /* SCTP_COMPAT_H */