sctp-socket 0.0.1 → 0.0.5
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.gitignore +1 -0
- data/CHANGES.md +22 -1
- data/Gemfile +2 -10
- data/README.md +18 -5
- data/Rakefile +10 -9
- data/ext/sctp/extconf.rb +2 -0
- data/ext/sctp/socket.c +679 -33
- data/sctp-socket.gemspec +12 -7
- data.tar.gz.sig +0 -0
- metadata +24 -21
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 319cf8cad773727889aed0c51508d4febfa4e145f9572ef2cdc265bdfc4c6ef2
|
4
|
+
data.tar.gz: aa085297b675c4f8a1468d689868a25ff6e9b9f5c954324801146b3878bdb150
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a26f8069a0034447ceadd4bb5e59af079da161e4ed0d2620de9df1809e072284fa2fc7aea0799f8f1d17f2da74de744ebc4fec399f21f93e0afa713092b5e0ca
|
7
|
+
data.tar.gz: 5267896027a79534c91c52396528654a9f046437ccf437be392d1609fbee72980cfd18116db8e85453048976a990084321089d6159822a5453d4ba155163581f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
-
##
|
1
|
+
## 0.0.5 - 15-Dec-2021
|
2
|
+
* Add handling for Linux platforms that don't support the sctp_sendv function
|
3
|
+
and/or the SCTP_SEND_FAILED_EVENT notification.
|
4
|
+
* Some minor updates to Rakefile and Gemfile.
|
2
5
|
|
6
|
+
## 0.0.4 - 3-Dec-2020
|
7
|
+
* Added the send method. Use this when you already have a connection.
|
8
|
+
* Fixed a flags bug in the sendmsg method.
|
9
|
+
* Fixed an association_id typo in the connect method.
|
10
|
+
* The SCTP_PR_SCTP_TTL flag is automatically set if a TTL value is provided.
|
11
|
+
* Added some constants so you can actually start passing flag values.
|
12
|
+
|
13
|
+
## 0.0.3 - 1-Dec-2020
|
14
|
+
* Added notification hooks that you can subscribe to, so now the subscribe method
|
15
|
+
actually does something.
|
16
|
+
|
17
|
+
## 0.0.2 - 29-Nov-2020
|
18
|
+
* Fixed the homepage link in the gemspec metadata. Thanks go to Nick LaMuro for the patch.
|
19
|
+
* The getlocalnames and getpeernames now return an array of addresses.
|
20
|
+
* Added a shutdown method.
|
21
|
+
* Added more documentation.
|
22
|
+
|
23
|
+
## 0.0.1 - 24-Nov-2020
|
3
24
|
* Initial release.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ On some systems, such as RHEL8, you may need to enable the sctp module.
|
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
15
|
-
|
15
|
+
`gem install sctp-socket`
|
16
16
|
|
17
17
|
## About SCTP
|
18
18
|
|
@@ -30,7 +30,7 @@ is applied to correct loss or corruption of data.
|
|
30
30
|
|
31
31
|
## Synopsis
|
32
32
|
|
33
|
-
```
|
33
|
+
```ruby
|
34
34
|
# sample_server.rb
|
35
35
|
require 'sctp/socket'
|
36
36
|
|
@@ -43,7 +43,7 @@ begin
|
|
43
43
|
socket.listen
|
44
44
|
|
45
45
|
while true
|
46
|
-
data = socket.
|
46
|
+
data = socket.recvmsg
|
47
47
|
puts data
|
48
48
|
end
|
49
49
|
ensure
|
@@ -53,15 +53,28 @@ end
|
|
53
53
|
|
54
54
|
## Future Plans
|
55
55
|
|
56
|
-
*
|
57
|
-
* Add specs.
|
56
|
+
* Add more constants.
|
57
|
+
* Add more specs.
|
58
|
+
* Add more notifications.
|
58
59
|
|
59
60
|
## Known Issues
|
60
61
|
|
62
|
+
Currently this has only been developed and tested on Linux. Other platforms
|
63
|
+
will probably only be supported via community contributions.
|
64
|
+
|
65
|
+
On Ubuntu 20 and possibly other Linux variants, the sendv method is not
|
66
|
+
available. Use the sendmsg method instead.
|
67
|
+
|
61
68
|
Please report any issues on the github project page.
|
62
69
|
|
63
70
|
https://github.com/djberg96/sctp-socket
|
64
71
|
|
72
|
+
## More Information on SCTP
|
73
|
+
|
74
|
+
* https://www.linuxjournal.com/article/9748
|
75
|
+
* https://www.linuxjournal.com/article/9749
|
76
|
+
* https://www.linuxjournal.com/article/9784
|
77
|
+
|
65
78
|
## License
|
66
79
|
|
67
80
|
Apache-2.0
|
data/Rakefile
CHANGED
@@ -6,20 +6,21 @@ require 'rake/extensiontask'
|
|
6
6
|
include RbConfig
|
7
7
|
|
8
8
|
CLEAN.include(
|
9
|
-
'**/*.gem',
|
10
|
-
'**/*.rbc',
|
11
|
-
'**/*.o',
|
12
|
-
'**/*.log',
|
13
|
-
'**/Makefile',
|
14
|
-
'**/conftest.dSYM',
|
15
|
-
"**/*.#{CONFIG['DLEXT']}" # C shared object
|
9
|
+
'**/*.gem', # Gem files
|
10
|
+
'**/*.rbc', # Rubinius
|
11
|
+
'**/*.o', # C object file
|
12
|
+
'**/*.log', # Ruby extension build log
|
13
|
+
'**/Makefile', # C Makefile
|
14
|
+
'**/conftest.dSYM', # OS X build directory
|
15
|
+
"**/*.#{CONFIG['DLEXT']}", # C shared object
|
16
|
+
'tmp' # Rake compiler
|
16
17
|
)
|
17
18
|
|
18
19
|
namespace :gem do
|
19
20
|
desc "Create the sys-uname gem"
|
20
21
|
task :create => [:clean] do
|
21
22
|
require 'rubygems/package'
|
22
|
-
spec =
|
23
|
+
spec = Gem::Specification.load('sctp-socket.gemspec')
|
23
24
|
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
24
25
|
Gem::Package.build(spec)
|
25
26
|
end
|
@@ -39,4 +40,4 @@ end
|
|
39
40
|
RSpec::Core::RakeTask.new
|
40
41
|
|
41
42
|
task :spec => :compile
|
42
|
-
task :default => :spec
|
43
|
+
task :default => [:clean, :spec]
|
data/ext/sctp/extconf.rb
CHANGED
data/ext/sctp/socket.c
CHANGED
@@ -7,6 +7,61 @@
|
|
7
7
|
VALUE mSCTP;
|
8
8
|
VALUE cSocket;
|
9
9
|
VALUE v_sndrcv_struct;
|
10
|
+
VALUE v_assoc_change_struct;
|
11
|
+
VALUE v_peeraddr_change_struct;
|
12
|
+
VALUE v_remote_error_struct;
|
13
|
+
VALUE v_send_failed_event_struct;
|
14
|
+
VALUE v_shutdown_event_struct;
|
15
|
+
VALUE v_sndinfo_struct;
|
16
|
+
VALUE v_adaptation_event_struct;
|
17
|
+
VALUE v_partial_delivery_event_struct;
|
18
|
+
VALUE v_auth_event_struct;
|
19
|
+
VALUE v_sockaddr_in_struct;
|
20
|
+
VALUE v_sctp_status_struct;
|
21
|
+
VALUE v_sctp_rtoinfo_struct;
|
22
|
+
VALUE v_sctp_associnfo_struct;
|
23
|
+
VALUE v_sctp_default_send_params_struct;
|
24
|
+
|
25
|
+
#if !defined(IOV_MAX)
|
26
|
+
#if defined(_SC_IOV_MAX)
|
27
|
+
#define IOV_MAX (sysconf(_SC_IOV_MAX))
|
28
|
+
#else
|
29
|
+
// Assume infinity, or let the syscall return with error
|
30
|
+
#define IOV_MAX INT_MAX
|
31
|
+
#endif
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#define ARY2IOVEC(iov,ary) \
|
35
|
+
do { \
|
36
|
+
VALUE *cur; \
|
37
|
+
struct iovec *tmp; \
|
38
|
+
long n; \
|
39
|
+
cur = RARRAY_PTR(ary); \
|
40
|
+
n = RARRAY_LEN(ary); \
|
41
|
+
iov = tmp = alloca(sizeof(struct iovec) * n); \
|
42
|
+
for (; --n >= 0; tmp++, cur++) { \
|
43
|
+
if (TYPE(*cur) != T_STRING) \
|
44
|
+
rb_raise(rb_eArgError, "must be an array of strings"); \
|
45
|
+
tmp->iov_base = RSTRING_PTR(*cur); \
|
46
|
+
tmp->iov_len = RSTRING_LEN(*cur); \
|
47
|
+
} \
|
48
|
+
} while (0)
|
49
|
+
|
50
|
+
// TODO: Yes, I know I need to update the signature.
|
51
|
+
VALUE convert_sockaddr_in_to_struct(struct sockaddr_in* addr){
|
52
|
+
char ipbuf[INET6_ADDRSTRLEN];
|
53
|
+
|
54
|
+
if(addr->sin_family == AF_INET6)
|
55
|
+
inet_ntop(addr->sin_family, &(((struct sockaddr_in6 *)addr)->sin6_addr), ipbuf, sizeof(ipbuf));
|
56
|
+
else
|
57
|
+
inet_ntop(addr->sin_family, &(((struct sockaddr_in *)addr)->sin_addr), ipbuf, sizeof(ipbuf));
|
58
|
+
|
59
|
+
return rb_struct_new(v_sockaddr_in_struct,
|
60
|
+
INT2NUM(addr->sin_family),
|
61
|
+
INT2NUM(ntohs(addr->sin_port)),
|
62
|
+
rb_str_new2(ipbuf)
|
63
|
+
);
|
64
|
+
}
|
10
65
|
|
11
66
|
// Helper function to get a hash value via string or symbol.
|
12
67
|
VALUE rb_hash_aref2(VALUE v_hash, const char* key){
|
@@ -26,8 +81,15 @@ VALUE rb_hash_aref2(VALUE v_hash, const char* key){
|
|
26
81
|
* a domain (aka family) value and socket type. By default these are AF_INET
|
27
82
|
* and SOCK_SEQPACKET, respectively.
|
28
83
|
*
|
84
|
+
* There are only two supported families: SOCK_SEQPACKET for the creation
|
85
|
+
* of a one-to-many socket, and SOCK_STREAM for the creation of a
|
86
|
+
* one-to-one socket.
|
87
|
+
*
|
29
88
|
* Example:
|
30
89
|
*
|
90
|
+
* require 'socket'
|
91
|
+
* require 'sctp/socket'
|
92
|
+
*
|
31
93
|
* socket1 = SCTP::Socket.new
|
32
94
|
* socket2 = SCTP::Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
|
33
95
|
*/
|
@@ -193,7 +255,7 @@ static VALUE rsctp_connect(int argc, VALUE* argv, VALUE self){
|
|
193
255
|
if(sctp_connectx(sock_fd, (struct sockaddr *) addrs, num_ip, &assoc) < 0)
|
194
256
|
rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
|
195
257
|
|
196
|
-
rb_iv_set(self, "@
|
258
|
+
rb_iv_set(self, "@association_id", INT2NUM(assoc));
|
197
259
|
|
198
260
|
return self;
|
199
261
|
}
|
@@ -215,16 +277,20 @@ static VALUE rsctp_close(VALUE self){
|
|
215
277
|
return self;
|
216
278
|
}
|
217
279
|
|
280
|
+
/*
|
281
|
+
* Return an array of all addresses of a peer.
|
282
|
+
*/
|
218
283
|
static VALUE rsctp_getpeernames(VALUE self){
|
219
|
-
VALUE v_assoc_id = rb_iv_get(self, "@assocation_id");
|
220
284
|
sctp_assoc_t assoc_id;
|
221
285
|
struct sockaddr* addrs;
|
222
286
|
int i, sock_fd, num_addrs;
|
287
|
+
char str[16];
|
288
|
+
VALUE v_array = rb_ary_new();
|
223
289
|
|
224
290
|
bzero(&addrs, sizeof(addrs));
|
225
291
|
|
226
292
|
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
227
|
-
assoc_id = NUM2INT(
|
293
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
228
294
|
|
229
295
|
num_addrs = sctp_getpaddrs(sock_fd, assoc_id, &addrs);
|
230
296
|
|
@@ -234,23 +300,36 @@ static VALUE rsctp_getpeernames(VALUE self){
|
|
234
300
|
}
|
235
301
|
|
236
302
|
for(i = 0; i < num_addrs; i++){
|
237
|
-
|
303
|
+
inet_ntop(AF_INET, &(((struct sockaddr_in *)&addrs[i])->sin_addr), str, sizeof(str));
|
304
|
+
rb_ary_push(v_array, rb_str_new2(str));
|
305
|
+
bzero(&str, sizeof(str));
|
238
306
|
}
|
239
307
|
|
240
308
|
sctp_freepaddrs(addrs);
|
241
309
|
|
242
|
-
return
|
310
|
+
return v_array;
|
243
311
|
}
|
244
312
|
|
313
|
+
/*
|
314
|
+
* Return an array of local addresses that are part of the association.
|
315
|
+
*
|
316
|
+
* Example:
|
317
|
+
*
|
318
|
+
* socket = SCTP::Socket.new
|
319
|
+
* socket.bind(:addresses => ['10.0.4.5', '10.0.5.5'])
|
320
|
+
* socket.getlocalnames # => ['10.0.4.5', '10.0.5.5'])
|
321
|
+
*/
|
245
322
|
static VALUE rsctp_getlocalnames(VALUE self){
|
246
323
|
sctp_assoc_t assoc_id;
|
247
324
|
struct sockaddr* addrs;
|
248
325
|
int i, sock_fd, num_addrs;
|
326
|
+
char str[16];
|
327
|
+
VALUE v_array = rb_ary_new();
|
249
328
|
|
250
329
|
bzero(&addrs, sizeof(addrs));
|
251
330
|
|
252
331
|
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
253
|
-
assoc_id = NUM2INT(rb_iv_get(self, "@
|
332
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
254
333
|
|
255
334
|
num_addrs = sctp_getladdrs(sock_fd, assoc_id, &addrs);
|
256
335
|
|
@@ -260,12 +339,152 @@ static VALUE rsctp_getlocalnames(VALUE self){
|
|
260
339
|
}
|
261
340
|
|
262
341
|
for(i = 0; i < num_addrs; i++){
|
263
|
-
|
342
|
+
inet_ntop(AF_INET, &(((struct sockaddr_in *)&addrs[i])->sin_addr), str, sizeof(str));
|
343
|
+
rb_ary_push(v_array, rb_str_new2(str));
|
344
|
+
bzero(&str, sizeof(str));
|
264
345
|
}
|
265
346
|
|
266
347
|
sctp_freeladdrs(addrs);
|
267
348
|
|
268
|
-
return
|
349
|
+
return v_array;
|
350
|
+
}
|
351
|
+
|
352
|
+
#ifdef HAVE_SCTP_SENDV
|
353
|
+
static VALUE rsctp_sendv(VALUE self, VALUE v_messages){
|
354
|
+
struct iovec* iov;
|
355
|
+
struct sockaddr* addrs[8];
|
356
|
+
struct sctp_sndinfo info;
|
357
|
+
int sock_fd, num_bytes, size;
|
358
|
+
|
359
|
+
Check_Type(v_messages, T_ARRAY);
|
360
|
+
bzero(&addrs, sizeof(addrs));
|
361
|
+
|
362
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
363
|
+
|
364
|
+
Check_Type(v_messages, T_ARRAY);
|
365
|
+
size = RARRAY_LEN(v_messages);
|
366
|
+
|
367
|
+
if(!size)
|
368
|
+
rb_raise(rb_eArgError, "Must contain at least one message");
|
369
|
+
|
370
|
+
if(size > IOV_MAX)
|
371
|
+
rb_raise(rb_eArgError, "Array size is greater than IOV_MAX");
|
372
|
+
|
373
|
+
ARY2IOVEC(iov, v_messages);
|
374
|
+
|
375
|
+
info.snd_flags = SCTP_UNORDERED;
|
376
|
+
info.snd_assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
377
|
+
|
378
|
+
num_bytes = sctp_sendv(
|
379
|
+
sock_fd,
|
380
|
+
iov,
|
381
|
+
size,
|
382
|
+
NULL,
|
383
|
+
0,
|
384
|
+
&info,
|
385
|
+
sizeof(info),
|
386
|
+
SCTP_SENDV_SNDINFO,
|
387
|
+
0
|
388
|
+
);
|
389
|
+
|
390
|
+
if(num_bytes < 0)
|
391
|
+
rb_raise(rb_eSystemCallError, "sctp_sendv: %s", strerror(errno));
|
392
|
+
|
393
|
+
return INT2NUM(num_bytes);
|
394
|
+
}
|
395
|
+
#endif
|
396
|
+
|
397
|
+
/*
|
398
|
+
* Send a message on an already-connected socket to a specific association.
|
399
|
+
*
|
400
|
+
* Example:
|
401
|
+
*
|
402
|
+
* socket = SCTP::Socket.new
|
403
|
+
* socket.connect(:port => 42000, :addresses => ['10.0.4.5', '10.0.5.5'])
|
404
|
+
*
|
405
|
+
* socket.send(:message => "Hello World")
|
406
|
+
* socket.send(:message => "Hello World", :association_id => 37)
|
407
|
+
*
|
408
|
+
*/
|
409
|
+
static VALUE rsctp_send(VALUE self, VALUE v_options){
|
410
|
+
uint16_t stream;
|
411
|
+
uint32_t ppid, send_flags, ctrl_flags, ttl, context;
|
412
|
+
ssize_t num_bytes;
|
413
|
+
int sock_fd;
|
414
|
+
sctp_assoc_t assoc_id;
|
415
|
+
struct sctp_sndrcvinfo info;
|
416
|
+
VALUE v_msg, v_stream, v_ppid, v_context, v_send_flags, v_ctrl_flags, v_ttl, v_assoc_id;
|
417
|
+
|
418
|
+
Check_Type(v_options, T_HASH);
|
419
|
+
|
420
|
+
v_msg = rb_hash_aref2(v_options, "message");
|
421
|
+
v_stream = rb_hash_aref2(v_options, "stream");
|
422
|
+
v_ppid = rb_hash_aref2(v_options, "ppid");
|
423
|
+
v_context = rb_hash_aref2(v_options, "context");
|
424
|
+
v_send_flags = rb_hash_aref2(v_options, "send_flags");
|
425
|
+
v_ctrl_flags = rb_hash_aref2(v_options, "control_flags");
|
426
|
+
v_ttl = rb_hash_aref2(v_options, "ttl");
|
427
|
+
v_assoc_id = rb_hash_aref2(v_options, "association_id");
|
428
|
+
|
429
|
+
if(NIL_P(v_stream))
|
430
|
+
stream = 0;
|
431
|
+
else
|
432
|
+
stream = NUM2INT(v_stream);
|
433
|
+
|
434
|
+
if(NIL_P(v_send_flags))
|
435
|
+
send_flags = 0;
|
436
|
+
else
|
437
|
+
send_flags = NUM2INT(v_send_flags);
|
438
|
+
|
439
|
+
if(NIL_P(v_ctrl_flags))
|
440
|
+
ctrl_flags = 0;
|
441
|
+
else
|
442
|
+
ctrl_flags = NUM2INT(v_ctrl_flags);
|
443
|
+
|
444
|
+
if(NIL_P(v_ttl)){
|
445
|
+
ttl = 0;
|
446
|
+
}
|
447
|
+
else{
|
448
|
+
ttl = NUM2INT(v_ttl);
|
449
|
+
send_flags |= SCTP_PR_SCTP_TTL;
|
450
|
+
}
|
451
|
+
|
452
|
+
if(NIL_P(v_ppid))
|
453
|
+
ppid = 0;
|
454
|
+
else
|
455
|
+
ppid = NUM2INT(v_ppid);
|
456
|
+
|
457
|
+
if(NIL_P(v_context))
|
458
|
+
context = 0;
|
459
|
+
else
|
460
|
+
context = NUM2INT(v_context);
|
461
|
+
|
462
|
+
if(NIL_P(v_assoc_id))
|
463
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
464
|
+
else
|
465
|
+
assoc_id = NUM2INT(v_assoc_id);
|
466
|
+
|
467
|
+
info.sinfo_stream = stream;
|
468
|
+
info.sinfo_flags = send_flags;
|
469
|
+
info.sinfo_ppid = ppid;
|
470
|
+
info.sinfo_context = context;
|
471
|
+
info.sinfo_timetolive = ttl;
|
472
|
+
info.sinfo_assoc_id = assoc_id;
|
473
|
+
|
474
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
475
|
+
|
476
|
+
num_bytes = sctp_send(
|
477
|
+
sock_fd,
|
478
|
+
StringValueCStr(v_msg),
|
479
|
+
RSTRING_LEN(v_msg),
|
480
|
+
&info,
|
481
|
+
ctrl_flags
|
482
|
+
);
|
483
|
+
|
484
|
+
if(num_bytes < 0)
|
485
|
+
rb_raise(rb_eSystemCallError, "sctp_send: %s", strerror(errno));
|
486
|
+
|
487
|
+
return INT2NUM(num_bytes);
|
269
488
|
}
|
270
489
|
|
271
490
|
/*
|
@@ -323,12 +542,15 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
323
542
|
if(NIL_P(v_flags))
|
324
543
|
flags = 0;
|
325
544
|
else
|
326
|
-
flags = NUM2INT(
|
545
|
+
flags = NUM2INT(v_flags);
|
327
546
|
|
328
|
-
if(NIL_P(v_ttl))
|
547
|
+
if(NIL_P(v_ttl)){
|
329
548
|
ttl = 0;
|
330
|
-
|
549
|
+
}
|
550
|
+
else{
|
331
551
|
ttl = NUM2INT(v_ttl);
|
552
|
+
flags |= SCTP_PR_SCTP_TTL;
|
553
|
+
}
|
332
554
|
|
333
555
|
if(NIL_P(v_ppid))
|
334
556
|
ppid = 0;
|
@@ -406,7 +628,7 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
406
628
|
* end
|
407
629
|
*/
|
408
630
|
static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
409
|
-
VALUE v_flags;
|
631
|
+
VALUE v_flags, v_notification, v_message;
|
410
632
|
struct sctp_sndrcvinfo sndrcvinfo;
|
411
633
|
struct sockaddr_in clientaddr;
|
412
634
|
int flags, bytes, sock_fd;
|
@@ -437,49 +659,215 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
437
659
|
if(bytes < 0)
|
438
660
|
rb_raise(rb_eSystemCallError, "sctp_recvmsg: %s", strerror(errno));
|
439
661
|
|
440
|
-
|
441
|
-
|
662
|
+
v_notification = Qnil;
|
663
|
+
|
442
664
|
if(flags & MSG_NOTIFICATION){
|
665
|
+
uint32_t i;
|
666
|
+
char str[16];
|
443
667
|
union sctp_notification* snp;
|
668
|
+
VALUE v_str;
|
669
|
+
VALUE* v_temp;
|
670
|
+
|
444
671
|
snp = (union sctp_notification*)buffer;
|
445
672
|
|
446
|
-
switch(snp->sn_type){
|
673
|
+
switch(snp->sn_header.sn_type){
|
447
674
|
case SCTP_ASSOC_CHANGE:
|
675
|
+
switch(snp->sn_assoc_change.sac_state){
|
676
|
+
case SCTP_COMM_LOST:
|
677
|
+
v_str = rb_str_new2("comm lost");
|
678
|
+
break;
|
679
|
+
case SCTP_COMM_UP:
|
680
|
+
v_str = rb_str_new2("comm up");
|
681
|
+
break;
|
682
|
+
case SCTP_RESTART:
|
683
|
+
v_str = rb_str_new2("restart");
|
684
|
+
break;
|
685
|
+
case SCTP_SHUTDOWN_COMP:
|
686
|
+
v_str = rb_str_new2("shutdown complete");
|
687
|
+
break;
|
688
|
+
case SCTP_CANT_STR_ASSOC:
|
689
|
+
v_str = rb_str_new2("association setup failed");
|
690
|
+
break;
|
691
|
+
default:
|
692
|
+
v_str = rb_str_new2("unknown");
|
693
|
+
}
|
694
|
+
|
695
|
+
v_notification = rb_struct_new(v_assoc_change_struct,
|
696
|
+
UINT2NUM(snp->sn_assoc_change.sac_type),
|
697
|
+
UINT2NUM(snp->sn_assoc_change.sac_length),
|
698
|
+
UINT2NUM(snp->sn_assoc_change.sac_state),
|
699
|
+
UINT2NUM(snp->sn_assoc_change.sac_error),
|
700
|
+
UINT2NUM(snp->sn_assoc_change.sac_outbound_streams),
|
701
|
+
UINT2NUM(snp->sn_assoc_change.sac_inbound_streams),
|
702
|
+
UINT2NUM(snp->sn_assoc_change.sac_assoc_id),
|
703
|
+
v_str
|
704
|
+
);
|
448
705
|
break;
|
449
706
|
case SCTP_PEER_ADDR_CHANGE:
|
707
|
+
switch(snp->sn_paddr_change.spc_state){
|
708
|
+
case SCTP_ADDR_AVAILABLE:
|
709
|
+
v_str = rb_str_new2("available");
|
710
|
+
break;
|
711
|
+
case SCTP_ADDR_UNREACHABLE:
|
712
|
+
v_str = rb_str_new2("unreachable");
|
713
|
+
break;
|
714
|
+
case SCTP_ADDR_REMOVED:
|
715
|
+
v_str = rb_str_new2("removed from association");
|
716
|
+
break;
|
717
|
+
case SCTP_ADDR_ADDED:
|
718
|
+
v_str = rb_str_new2("added to association");
|
719
|
+
break;
|
720
|
+
case SCTP_ADDR_MADE_PRIM:
|
721
|
+
v_str = rb_str_new2("primary destination");
|
722
|
+
break;
|
723
|
+
default:
|
724
|
+
v_str = rb_str_new2("unknown");
|
725
|
+
}
|
726
|
+
|
727
|
+
inet_ntop(
|
728
|
+
((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_family,
|
729
|
+
&(((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_addr),
|
730
|
+
str,
|
731
|
+
sizeof(str)
|
732
|
+
);
|
733
|
+
|
734
|
+
v_notification = rb_struct_new(v_peeraddr_change_struct,
|
735
|
+
UINT2NUM(snp->sn_paddr_change.spc_type),
|
736
|
+
UINT2NUM(snp->sn_paddr_change.spc_length),
|
737
|
+
rb_str_new2(str),
|
738
|
+
UINT2NUM(snp->sn_paddr_change.spc_state),
|
739
|
+
UINT2NUM(snp->sn_paddr_change.spc_error),
|
740
|
+
UINT2NUM(snp->sn_paddr_change.spc_assoc_id),
|
741
|
+
v_str
|
742
|
+
);
|
450
743
|
break;
|
451
744
|
case SCTP_REMOTE_ERROR:
|
745
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_remote_error.sre_length);
|
746
|
+
|
747
|
+
for(i = 0; i < snp->sn_remote_error.sre_length; i++){
|
748
|
+
v_temp[i] = UINT2NUM(snp->sn_remote_error.sre_data[i]);
|
749
|
+
}
|
750
|
+
|
751
|
+
v_notification = rb_struct_new(v_remote_error_struct,
|
752
|
+
UINT2NUM(snp->sn_remote_error.sre_type),
|
753
|
+
UINT2NUM(snp->sn_remote_error.sre_length),
|
754
|
+
UINT2NUM(snp->sn_remote_error.sre_error),
|
755
|
+
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
756
|
+
rb_ary_new4(snp->sn_remote_error.sre_length, v_temp)
|
757
|
+
);
|
758
|
+
break;
|
759
|
+
#ifdef SCTP_SEND_FAILED_EVENT
|
760
|
+
case SCTP_SEND_FAILED_EVENT:
|
761
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed_event.ssf_length);
|
762
|
+
|
763
|
+
for(i = 0; i < snp->sn_send_failed_event.ssf_length; i++){
|
764
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssf_data[i]);
|
765
|
+
}
|
766
|
+
|
767
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
768
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_type),
|
769
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_length),
|
770
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_error),
|
771
|
+
rb_struct_new(v_sndinfo_struct,
|
772
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
|
773
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
|
774
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
|
775
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
|
776
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
|
777
|
+
),
|
778
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_assoc_id),
|
779
|
+
rb_ary_new4(snp->sn_send_failed_event.ssf_length, v_temp)
|
780
|
+
);
|
452
781
|
break;
|
782
|
+
#else
|
453
783
|
case SCTP_SEND_FAILED:
|
784
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed.ssf_length);
|
785
|
+
|
786
|
+
for(i = 0; i < snp->sn_send_failed.ssf_length; i++){
|
787
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed.ssf_data[i]);
|
788
|
+
}
|
789
|
+
|
790
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
791
|
+
UINT2NUM(snp->sn_send_failed.ssf_type),
|
792
|
+
UINT2NUM(snp->sn_send_failed.ssf_length),
|
793
|
+
UINT2NUM(snp->sn_send_failed.ssf_error),
|
794
|
+
Qnil,
|
795
|
+
UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
|
796
|
+
rb_ary_new4(snp->sn_send_failed.ssf_length, v_temp)
|
797
|
+
);
|
454
798
|
break;
|
799
|
+
#endif
|
455
800
|
case SCTP_SHUTDOWN_EVENT:
|
801
|
+
v_notification = rb_struct_new(v_shutdown_event_struct,
|
802
|
+
UINT2NUM(snp->sn_shutdown_event.sse_type),
|
803
|
+
UINT2NUM(snp->sn_shutdown_event.sse_length),
|
804
|
+
UINT2NUM(snp->sn_shutdown_event.sse_assoc_id)
|
805
|
+
);
|
456
806
|
break;
|
457
807
|
case SCTP_ADAPTATION_INDICATION:
|
808
|
+
v_notification = rb_struct_new(v_adaptation_event_struct,
|
809
|
+
UINT2NUM(snp->sn_adaptation_event.sai_type),
|
810
|
+
UINT2NUM(snp->sn_adaptation_event.sai_length),
|
811
|
+
UINT2NUM(snp->sn_adaptation_event.sai_adaptation_ind),
|
812
|
+
UINT2NUM(snp->sn_adaptation_event.sai_assoc_id)
|
813
|
+
);
|
458
814
|
break;
|
459
815
|
case SCTP_PARTIAL_DELIVERY_EVENT:
|
816
|
+
v_notification = rb_struct_new(v_partial_delivery_event_struct,
|
817
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_type),
|
818
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_length),
|
819
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_indication),
|
820
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_stream),
|
821
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_seq),
|
822
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_assoc_id)
|
823
|
+
);
|
824
|
+
break;
|
825
|
+
case SCTP_AUTHENTICATION_EVENT:
|
826
|
+
v_notification = rb_struct_new(v_auth_event_struct,
|
827
|
+
UINT2NUM(snp->sn_authkey_event.auth_type),
|
828
|
+
UINT2NUM(snp->sn_authkey_event.auth_length),
|
829
|
+
UINT2NUM(snp->sn_authkey_event.auth_keynumber),
|
830
|
+
UINT2NUM(snp->sn_authkey_event.auth_indication),
|
831
|
+
UINT2NUM(snp->sn_authkey_event.auth_assoc_id)
|
832
|
+
);
|
460
833
|
break;
|
461
834
|
}
|
462
835
|
}
|
463
|
-
|
836
|
+
|
837
|
+
if(NIL_P(v_notification))
|
838
|
+
v_message = rb_str_new(buffer, bytes);
|
839
|
+
else
|
840
|
+
v_message = Qnil;
|
464
841
|
|
465
842
|
return rb_struct_new(v_sndrcv_struct,
|
466
|
-
|
843
|
+
v_message,
|
467
844
|
UINT2NUM(sndrcvinfo.sinfo_stream),
|
468
845
|
UINT2NUM(sndrcvinfo.sinfo_flags),
|
469
846
|
UINT2NUM(sndrcvinfo.sinfo_ppid),
|
470
847
|
UINT2NUM(sndrcvinfo.sinfo_context),
|
471
848
|
UINT2NUM(sndrcvinfo.sinfo_timetolive),
|
472
|
-
UINT2NUM(sndrcvinfo.sinfo_assoc_id)
|
849
|
+
UINT2NUM(sndrcvinfo.sinfo_assoc_id),
|
850
|
+
v_notification,
|
851
|
+
convert_sockaddr_in_to_struct(&clientaddr)
|
473
852
|
);
|
474
853
|
}
|
475
854
|
|
476
855
|
/*
|
477
|
-
*
|
478
|
-
*
|
479
|
-
*
|
480
|
-
*
|
481
|
-
*
|
482
|
-
*
|
856
|
+
* Set the initial parameters used by the socket when sending out the INIT message.
|
857
|
+
*
|
858
|
+
* Example:
|
859
|
+
*
|
860
|
+
* socket = SCTP::Socket.new
|
861
|
+
* socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4, :timeout => 30)
|
862
|
+
*
|
863
|
+
* The following parameters can be configured:
|
864
|
+
*
|
865
|
+
* :output_streams - The number of outbound SCTP streams an application would like to request.
|
866
|
+
* :input_streams - The maximum number of inbound streams an application is prepared to allow.
|
867
|
+
* :max_attempts - How many times the the SCTP stack should send the initial INIT message before it's considered unreachable.
|
868
|
+
* :timeout - The maximum RTO value for the INIT timer.
|
869
|
+
*
|
870
|
+
* By default these values are set to zero (i.e. ignored).
|
483
871
|
*/
|
484
872
|
static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
485
873
|
int sock_fd;
|
@@ -519,7 +907,7 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
519
907
|
* as follows:
|
520
908
|
*
|
521
909
|
* :association
|
522
|
-
* - A change has occurred to an
|
910
|
+
* - A change has occurred to an association, either a new one has begun or an existing one has end.
|
523
911
|
*
|
524
912
|
* :address
|
525
913
|
* - The state of one of the peer's addresses has experienced a change.
|
@@ -530,14 +918,19 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
530
918
|
* :shutdown
|
531
919
|
* - The peer has sent a shutdown to the local endpoint.
|
532
920
|
*
|
921
|
+
* :data_io
|
922
|
+
* - Message data was received. On by default.
|
923
|
+
*
|
533
924
|
* Others:
|
534
925
|
*
|
535
|
-
* :
|
536
|
-
* :
|
537
|
-
* :data_io
|
538
|
-
* :peer_error
|
926
|
+
* :adaptation
|
927
|
+
* :authentication
|
539
928
|
* :partial_delivery
|
929
|
+
*
|
930
|
+
* Not yet supported:
|
931
|
+
*
|
540
932
|
* :sender_dry
|
933
|
+
* :peer_error
|
541
934
|
*
|
542
935
|
* By default only data_io is subscribed to.
|
543
936
|
*
|
@@ -565,7 +958,11 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
|
565
958
|
events.sctp_address_event = 1;
|
566
959
|
|
567
960
|
if(RTEST(rb_hash_aref2(v_options, "send_failure")))
|
961
|
+
#ifdef HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE_SCTP_SEND_FAILURE_EVENT
|
568
962
|
events.sctp_send_failure_event = 1;
|
963
|
+
#else
|
964
|
+
events.sctp_send_failure_event_event = 1;
|
965
|
+
#endif
|
569
966
|
|
570
967
|
if(RTEST(rb_hash_aref2(v_options, "peer_error")))
|
571
968
|
events.sctp_peer_error_event = 1;
|
@@ -645,13 +1042,220 @@ static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
|
|
645
1042
|
return self;
|
646
1043
|
}
|
647
1044
|
|
1045
|
+
static VALUE rsctp_get_default_send_params(VALUE self){
|
1046
|
+
int sock_fd;
|
1047
|
+
socklen_t size;
|
1048
|
+
sctp_assoc_t assoc_id;
|
1049
|
+
struct sctp_sndrcvinfo sndrcv;
|
1050
|
+
|
1051
|
+
bzero(&sndrcv, sizeof(sndrcv));
|
1052
|
+
|
1053
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
1054
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1055
|
+
size = sizeof(struct sctp_sndrcvinfo);
|
1056
|
+
|
1057
|
+
if(sctp_opt_info(sock_fd, assoc_id, SCTP_DEFAULT_SEND_PARAM, (void*)&sndrcv, &size) < 0)
|
1058
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1059
|
+
|
1060
|
+
return rb_struct_new(
|
1061
|
+
v_sctp_default_send_params_struct,
|
1062
|
+
INT2NUM(sndrcv.sinfo_stream),
|
1063
|
+
INT2NUM(sndrcv.sinfo_ssn),
|
1064
|
+
INT2NUM(sndrcv.sinfo_flags),
|
1065
|
+
INT2NUM(sndrcv.sinfo_ppid),
|
1066
|
+
INT2NUM(sndrcv.sinfo_context),
|
1067
|
+
INT2NUM(sndrcv.sinfo_timetolive),
|
1068
|
+
INT2NUM(sndrcv.sinfo_tsn),
|
1069
|
+
INT2NUM(sndrcv.sinfo_cumtsn),
|
1070
|
+
INT2NUM(sndrcv.sinfo_assoc_id)
|
1071
|
+
);
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
static VALUE rsctp_get_association_info(VALUE self){
|
1075
|
+
int sock_fd;
|
1076
|
+
socklen_t size;
|
1077
|
+
sctp_assoc_t assoc_id;
|
1078
|
+
struct sctp_assocparams assoc;
|
1079
|
+
|
1080
|
+
bzero(&assoc, sizeof(assoc));
|
1081
|
+
|
1082
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
1083
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1084
|
+
size = sizeof(struct sctp_assocparams);
|
1085
|
+
|
1086
|
+
if(sctp_opt_info(sock_fd, assoc_id, SCTP_ASSOCINFO, (void*)&assoc, &size) < 0)
|
1087
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1088
|
+
|
1089
|
+
return rb_struct_new(
|
1090
|
+
v_sctp_associnfo_struct,
|
1091
|
+
INT2NUM(assoc.sasoc_assoc_id),
|
1092
|
+
INT2NUM(assoc.sasoc_asocmaxrxt),
|
1093
|
+
INT2NUM(assoc.sasoc_number_peer_destinations),
|
1094
|
+
INT2NUM(assoc.sasoc_peer_rwnd),
|
1095
|
+
INT2NUM(assoc.sasoc_local_rwnd),
|
1096
|
+
INT2NUM(assoc.sasoc_cookie_life)
|
1097
|
+
);
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
1101
|
+
int how, sock_fd;
|
1102
|
+
VALUE v_how;
|
1103
|
+
|
1104
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
1105
|
+
|
1106
|
+
rb_scan_args(argc, argv, "01", &v_how);
|
1107
|
+
|
1108
|
+
if(NIL_P(v_how)){
|
1109
|
+
how = SHUT_RDWR;
|
1110
|
+
}
|
1111
|
+
else{
|
1112
|
+
Check_Type(v_how, T_FIXNUM);
|
1113
|
+
how = NUM2INT(v_how);
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
if(shutdown(sock_fd, how) < 0)
|
1117
|
+
rb_raise(rb_eSystemCallError, "shutdown: %s", strerror(errno));
|
1118
|
+
|
1119
|
+
return self;
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
static VALUE rsctp_get_retransmission_info(VALUE self){
|
1123
|
+
int sock_fd;
|
1124
|
+
socklen_t size;
|
1125
|
+
sctp_assoc_t assoc_id;
|
1126
|
+
struct sctp_rtoinfo rto;
|
1127
|
+
|
1128
|
+
bzero(&rto, sizeof(rto));
|
1129
|
+
|
1130
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
1131
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1132
|
+
size = sizeof(struct sctp_rtoinfo);
|
1133
|
+
|
1134
|
+
if(sctp_opt_info(sock_fd, assoc_id, SCTP_RTOINFO, (void*)&rto, &size) < 0)
|
1135
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1136
|
+
|
1137
|
+
return rb_struct_new(
|
1138
|
+
v_sctp_rtoinfo_struct,
|
1139
|
+
INT2NUM(rto.srto_assoc_id),
|
1140
|
+
INT2NUM(rto.srto_initial),
|
1141
|
+
INT2NUM(rto.srto_max),
|
1142
|
+
INT2NUM(rto.srto_min)
|
1143
|
+
);
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
static VALUE rsctp_get_status(VALUE self){
|
1147
|
+
int sock_fd;
|
1148
|
+
socklen_t size;
|
1149
|
+
sctp_assoc_t assoc_id;
|
1150
|
+
struct sctp_status status;
|
1151
|
+
struct sctp_paddrinfo* spinfo;
|
1152
|
+
char tmpname[INET_ADDRSTRLEN];
|
1153
|
+
|
1154
|
+
bzero(&status, sizeof(status));
|
1155
|
+
|
1156
|
+
sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
|
1157
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1158
|
+
size = sizeof(struct sctp_status);
|
1159
|
+
|
1160
|
+
if(sctp_opt_info(sock_fd, assoc_id, SCTP_STATUS, (void*)&status, &size) < 0)
|
1161
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1162
|
+
|
1163
|
+
spinfo = &status.sstat_primary;
|
1164
|
+
|
1165
|
+
if (spinfo->spinfo_address.ss_family == AF_INET6) {
|
1166
|
+
struct sockaddr_in6 *sin6;
|
1167
|
+
sin6 = (struct sockaddr_in6 *)&spinfo->spinfo_address;
|
1168
|
+
inet_ntop(AF_INET6, &sin6->sin6_addr, tmpname, sizeof (tmpname));
|
1169
|
+
}
|
1170
|
+
else {
|
1171
|
+
struct sockaddr_in *sin;
|
1172
|
+
sin = (struct sockaddr_in *)&spinfo->spinfo_address;
|
1173
|
+
inet_ntop(AF_INET, &sin->sin_addr, tmpname, sizeof (tmpname));
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
return rb_struct_new(v_sctp_status_struct,
|
1177
|
+
INT2NUM(status.sstat_assoc_id),
|
1178
|
+
INT2NUM(status.sstat_state),
|
1179
|
+
INT2NUM(status.sstat_rwnd),
|
1180
|
+
INT2NUM(status.sstat_unackdata),
|
1181
|
+
INT2NUM(status.sstat_penddata),
|
1182
|
+
INT2NUM(status.sstat_instrms),
|
1183
|
+
INT2NUM(status.sstat_outstrms),
|
1184
|
+
INT2NUM(status.sstat_fragmentation_point),
|
1185
|
+
rb_str_new2(tmpname)
|
1186
|
+
);
|
1187
|
+
}
|
1188
|
+
|
648
1189
|
void Init_socket(){
|
649
1190
|
mSCTP = rb_define_module("SCTP");
|
650
1191
|
cSocket = rb_define_class_under(mSCTP, "Socket", rb_cObject);
|
651
1192
|
|
652
1193
|
v_sndrcv_struct = rb_struct_define(
|
653
|
-
"
|
654
|
-
"ppid", "context", "ttl", "
|
1194
|
+
"SendReceiveInfo", "message", "stream", "flags",
|
1195
|
+
"ppid", "context", "ttl", "association_id", "notification", "client", NULL
|
1196
|
+
);
|
1197
|
+
|
1198
|
+
v_assoc_change_struct = rb_struct_define(
|
1199
|
+
"AssocChange", "type", "length", "state", "error",
|
1200
|
+
"outbound_streams", "inbound_streams", "association_id", "info", NULL
|
1201
|
+
);
|
1202
|
+
|
1203
|
+
v_peeraddr_change_struct = rb_struct_define(
|
1204
|
+
"PeerAddrChange", "type", "length", "ip_address",
|
1205
|
+
"state", "error", "association_id", "info", NULL
|
1206
|
+
);
|
1207
|
+
|
1208
|
+
v_remote_error_struct = rb_struct_define(
|
1209
|
+
"RemoteError", "type", "length", "error", "association_id", "data", NULL
|
1210
|
+
);
|
1211
|
+
|
1212
|
+
v_send_failed_event_struct = rb_struct_define(
|
1213
|
+
"SendFailedEvent", "type", "length", "error", "association_id", "data", NULL
|
1214
|
+
);
|
1215
|
+
|
1216
|
+
v_shutdown_event_struct = rb_struct_define(
|
1217
|
+
"ShutdownEvent", "type", "length", "association_id", NULL
|
1218
|
+
);
|
1219
|
+
|
1220
|
+
v_sndinfo_struct = rb_struct_define(
|
1221
|
+
"SendInfo", "sid", "flags", "ppid", "context", "association_id", NULL
|
1222
|
+
);
|
1223
|
+
|
1224
|
+
v_adaptation_event_struct = rb_struct_define(
|
1225
|
+
"AdaptationEvent", "type", "length", "adaptation_indication", "association_id", NULL
|
1226
|
+
);
|
1227
|
+
|
1228
|
+
v_partial_delivery_event_struct = rb_struct_define(
|
1229
|
+
"PartialDeliveryEvent", "type", "length", "indication", "stream",
|
1230
|
+
"sequence_number", "association_id", NULL
|
1231
|
+
);
|
1232
|
+
|
1233
|
+
v_auth_event_struct = rb_struct_define(
|
1234
|
+
"AuthEvent", "type", "length", "key_number", "indication", "association_id", NULL
|
1235
|
+
);
|
1236
|
+
|
1237
|
+
v_sockaddr_in_struct = rb_struct_define(
|
1238
|
+
"SockAddrIn", "family", "port", "address", NULL
|
1239
|
+
);
|
1240
|
+
|
1241
|
+
v_sctp_status_struct = rb_struct_define(
|
1242
|
+
"Status", "association_id", "state", "receive_window", "unacknowledged_data",
|
1243
|
+
"pending_data", "inbound_streams", "outbound_streams", "fragmentation_point", "primary", NULL
|
1244
|
+
);
|
1245
|
+
|
1246
|
+
v_sctp_rtoinfo_struct = rb_struct_define(
|
1247
|
+
"RetransmissionInfo", "association_id", "initial", "max", "min", NULL
|
1248
|
+
);
|
1249
|
+
|
1250
|
+
v_sctp_associnfo_struct = rb_struct_define(
|
1251
|
+
"AssociationInfo", "association_id", "max_retransmission_count",
|
1252
|
+
"number_peer_destinations", "peer_receive_window", "local_receive_window",
|
1253
|
+
"cookie_life", NULL
|
1254
|
+
);
|
1255
|
+
|
1256
|
+
v_sctp_default_send_params_struct = rb_struct_define(
|
1257
|
+
"DefaultSendParams", "stream", "ssn", "flags", "ppid", "context",
|
1258
|
+
"ttl", "tsn", "cumtsn", "association_id", NULL
|
655
1259
|
);
|
656
1260
|
|
657
1261
|
rb_define_method(cSocket, "initialize", rsctp_init, -1);
|
@@ -661,11 +1265,22 @@ void Init_socket(){
|
|
661
1265
|
rb_define_method(cSocket, "connect", rsctp_connect, -1);
|
662
1266
|
rb_define_method(cSocket, "getpeernames", rsctp_getpeernames, 0);
|
663
1267
|
rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames, 0);
|
1268
|
+
rb_define_method(cSocket, "get_status", rsctp_get_status, 0);
|
1269
|
+
rb_define_method(cSocket, "get_default_send_params", rsctp_get_default_send_params, 0);
|
1270
|
+
rb_define_method(cSocket, "get_retransmission_info", rsctp_get_retransmission_info, 0);
|
1271
|
+
rb_define_method(cSocket, "get_association_info", rsctp_get_association_info, 0);
|
664
1272
|
rb_define_method(cSocket, "listen", rsctp_listen, -1);
|
665
1273
|
rb_define_method(cSocket, "peeloff!", rsctp_peeloff, 1);
|
666
1274
|
rb_define_method(cSocket, "recvmsg", rsctp_recvmsg, -1);
|
1275
|
+
rb_define_method(cSocket, "send", rsctp_send, 1);
|
1276
|
+
|
1277
|
+
#ifdef HAVE_SCTP_SENDV
|
1278
|
+
rb_define_method(cSocket, "sendv", rsctp_sendv, 1);
|
1279
|
+
#endif
|
1280
|
+
|
667
1281
|
rb_define_method(cSocket, "sendmsg", rsctp_sendmsg, 1);
|
668
1282
|
rb_define_method(cSocket, "set_initmsg", rsctp_set_initmsg, 1);
|
1283
|
+
rb_define_method(cSocket, "shutdown", rsctp_shutdown, -1);
|
669
1284
|
rb_define_method(cSocket, "subscribe", rsctp_subscribe, 1);
|
670
1285
|
|
671
1286
|
rb_define_attr(cSocket, "domain", 1, 1);
|
@@ -674,6 +1289,37 @@ void Init_socket(){
|
|
674
1289
|
rb_define_attr(cSocket, "association_id", 1, 1);
|
675
1290
|
rb_define_attr(cSocket, "port", 1, 1);
|
676
1291
|
|
677
|
-
/* 0.0.
|
678
|
-
rb_define_const(cSocket, "VERSION", rb_str_new2("0.0.
|
1292
|
+
/* 0.0.5: The version of this library */
|
1293
|
+
rb_define_const(cSocket, "VERSION", rb_str_new2("0.0.5"));
|
1294
|
+
|
1295
|
+
/* send flags */
|
1296
|
+
|
1297
|
+
/* Message is unordered */
|
1298
|
+
rb_define_const(cSocket, "SCTP_UNORDERED", INT2NUM(SCTP_UNORDERED));
|
1299
|
+
|
1300
|
+
/* Override the primary address */
|
1301
|
+
rb_define_const(cSocket, "SCTP_ADDR_OVER", INT2NUM(SCTP_ADDR_OVER));
|
1302
|
+
|
1303
|
+
/* Send an ABORT to peer */
|
1304
|
+
rb_define_const(cSocket, "SCTP_ABORT", INT2NUM(SCTP_ABORT));
|
1305
|
+
|
1306
|
+
/* Start a shutdown procedure */
|
1307
|
+
rb_define_const(cSocket, "SCTP_EOF", INT2NUM(SCTP_EOF));
|
1308
|
+
|
1309
|
+
/* Send to all associations */
|
1310
|
+
rb_define_const(cSocket, "SCTP_SENDALL", INT2NUM(SCTP_SENDALL));
|
1311
|
+
|
1312
|
+
rb_define_const(cSocket, "MSG_NOTIFICATION", INT2NUM(MSG_NOTIFICATION));
|
1313
|
+
|
1314
|
+
// ASSOCIATION STATES //
|
1315
|
+
|
1316
|
+
rb_define_const(cSocket, "SCTP_EMPTY", INT2NUM(SCTP_EMPTY));
|
1317
|
+
rb_define_const(cSocket, "SCTP_CLOSED", INT2NUM(SCTP_CLOSED));
|
1318
|
+
rb_define_const(cSocket, "SCTP_COOKIE_WAIT", INT2NUM(SCTP_COOKIE_WAIT));
|
1319
|
+
rb_define_const(cSocket, "SCTP_COOKIE_ECHOED", INT2NUM(SCTP_COOKIE_ECHOED));
|
1320
|
+
rb_define_const(cSocket, "SCTP_ESTABLISHED", INT2NUM(SCTP_ESTABLISHED));
|
1321
|
+
rb_define_const(cSocket, "SCTP_SHUTDOWN_PENDING", INT2NUM(SCTP_SHUTDOWN_PENDING));
|
1322
|
+
rb_define_const(cSocket, "SCTP_SHUTDOWN_SENT", INT2NUM(SCTP_SHUTDOWN_SENT));
|
1323
|
+
rb_define_const(cSocket, "SCTP_SHUTDOWN_RECEIVED", INT2NUM(SCTP_SHUTDOWN_RECEIVED));
|
1324
|
+
rb_define_const(cSocket, "SCTP_SHUTDOWN_ACK_SENT", INT2NUM(SCTP_SHUTDOWN_ACK_SENT));
|
679
1325
|
}
|
data/sctp-socket.gemspec
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'sctp-socket'
|
3
|
-
spec.version = '0.0.
|
3
|
+
spec.version = '0.0.5'
|
4
4
|
spec.author = 'Daniel Berger'
|
5
5
|
spec.email = 'djberg96@gmail.com'
|
6
6
|
spec.summary = 'Ruby bindings for SCTP sockets'
|
7
|
-
spec.
|
8
|
-
spec.homepage = 'https://github.com/djberg96/sctp-sockets'
|
7
|
+
spec.homepage = 'https://github.com/djberg96/sctp-socket'
|
9
8
|
spec.license = 'Apache-2.0'
|
10
9
|
spec.cert_chain = ['certs/djberg96_pub.pem']
|
11
10
|
|
@@ -15,8 +14,14 @@ Gem::Specification.new do |spec|
|
|
15
14
|
|
16
15
|
spec.extensions = ['ext/sctp/extconf.rb']
|
17
16
|
|
18
|
-
spec.add_development_dependency 'bundler'
|
19
|
-
spec.add_development_dependency 'rake'
|
20
|
-
spec.add_development_dependency 'rake-compiler'
|
21
|
-
spec.add_development_dependency 'rspec'
|
17
|
+
spec.add_development_dependency 'bundler', '~> 2.1'
|
18
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
19
|
+
spec.add_development_dependency 'rake-compiler', '~> 1.1'
|
20
|
+
spec.add_development_dependency 'rspec', '~> 3.9'
|
21
|
+
|
22
|
+
spec.description = <<-EOF
|
23
|
+
The sctp-socket library provides Ruby bindings for SCTP sockets. is a
|
24
|
+
message oriented, reliable transport protocol with direct support for
|
25
|
+
multihoming.
|
26
|
+
EOF
|
22
27
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sctp-socket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Berger
|
@@ -35,65 +35,68 @@ cert_chain:
|
|
35
35
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
36
36
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2021-12-15 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: bundler
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '2.1'
|
47
47
|
type: :development
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '2.1'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: rake
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '0'
|
60
|
+
version: '13.0'
|
61
61
|
type: :development
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '0'
|
67
|
+
version: '13.0'
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: rake-compiler
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '1.1'
|
75
75
|
type: :development
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- - "
|
79
|
+
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '1.1'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: rspec
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
|
-
- - "
|
86
|
+
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '3.9'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
91
|
version_requirements: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
96
|
-
description:
|
95
|
+
version: '3.9'
|
96
|
+
description: |2
|
97
|
+
The sctp-socket library provides Ruby bindings for SCTP sockets. is a
|
98
|
+
message oriented, reliable transport protocol with direct support for
|
99
|
+
multihoming.
|
97
100
|
email: djberg96@gmail.com
|
98
101
|
executables: []
|
99
102
|
extensions:
|
@@ -116,7 +119,7 @@ files:
|
|
116
119
|
- ext/sctp/socket/client.c
|
117
120
|
- ext/sctp/socket/server.c
|
118
121
|
- sctp-socket.gemspec
|
119
|
-
homepage: https://github.com/djberg96/sctp-
|
122
|
+
homepage: https://github.com/djberg96/sctp-socket
|
120
123
|
licenses:
|
121
124
|
- Apache-2.0
|
122
125
|
metadata: {}
|
@@ -135,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
138
|
- !ruby/object:Gem::Version
|
136
139
|
version: '0'
|
137
140
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
141
|
+
rubygems_version: 3.2.25
|
139
142
|
signing_key:
|
140
143
|
specification_version: 4
|
141
144
|
summary: Ruby bindings for SCTP sockets
|
metadata.gz.sig
CHANGED
Binary file
|