sctp-socket 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|