sctp-socket 0.0.6 → 0.1.0
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/CHANGES.md +22 -0
- data/README.md +1 -1
- data/examples/client_example.rb +3 -2
- data/examples/server_example.rb +1 -1
- data/ext/sctp/extconf.rb +1 -0
- data/ext/sctp/socket.c +393 -95
- data/sctp-socket.gemspec +5 -5
- data.tar.gz.sig +0 -0
- metadata +18 -18
- 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: a483264dd5712655f641ade00e03177756f25340c2fd398bed3ad453bc6a9cdb
|
4
|
+
data.tar.gz: 719857e2ce3a5db341aa317f23ec0bf2fa674dd9b427b502f99e3515cb786dac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3dd98e9076f37396a55339fa20f1097ab5c582a418d885d8599b320b5cf722acb3c296b8afb798faadbee67519ee9368e87596c60d8658ef35a23a01d76c0d82
|
7
|
+
data.tar.gz: 4c7adf403e6075eb53129e9f4b92a97e3887518afa15458bf8b74fa7765478c54001d5f5f6cd997c2a4e44e1cba8783ee329ff9c3125f62fb9ae87e53c7e06b7
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 0.1.0 - 31-May-2024
|
2
|
+
* Added support for sender dry events.
|
3
|
+
* Added the get_peer_address_params method.
|
4
|
+
* Comments were added to methods that were missing them.
|
5
|
+
* Remove version locking for dev dependencies, doesn't matter to me.
|
6
|
+
* Bumped version to 0.1.0, I guess I'll declare it stable.
|
7
|
+
|
8
|
+
## 0.0.7 - 28-May-2024
|
9
|
+
* Added the recvv method.
|
10
|
+
* The getlocalnames and getpeernames methods now accept optional fileno and
|
11
|
+
association ID arguments.
|
12
|
+
* The peeloff method now returns the peeled off fileno and no longer modifies
|
13
|
+
the receiver, so I dropped the exclamation point from the method name.
|
14
|
+
* Added the get_subscriptions method.
|
15
|
+
* Changed bind method to bindx and connect method to connectx. I may try to
|
16
|
+
subclass Socket someday so I didn't want a conflict, and this more closely
|
17
|
+
matches the underlying function name anyway.
|
18
|
+
* Changed the sock_fd method to fileno.
|
19
|
+
* Changed the default backlog from 1024 to 128 for the listen method.
|
20
|
+
* Updated comments and documentation.
|
21
|
+
* Added more specs.
|
22
|
+
|
1
23
|
## 0.0.6 - 24-May-2024
|
2
24
|
* Fixup the sendv method and add some documentation.
|
3
25
|
* Added documentation to the get_status method.
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ require 'sctp/socket'
|
|
39
39
|
begin
|
40
40
|
port = 62324
|
41
41
|
socket = SCTP::Socket.new
|
42
|
-
socket.
|
42
|
+
socket.bindx(:port => port, :addresses => ['10.0.5.4', '10.0.6.4'])
|
43
43
|
socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4)
|
44
44
|
socket.subscribe(:data_io => true)
|
45
45
|
socket.listen
|
data/examples/client_example.rb
CHANGED
@@ -10,10 +10,11 @@ begin
|
|
10
10
|
socket = SCTP::Socket.new
|
11
11
|
|
12
12
|
# Optional, but could bind to a subset of available addresses
|
13
|
-
p socket.
|
13
|
+
p socket.bindx(:addresses => addresses)
|
14
14
|
|
15
15
|
# Initial connection
|
16
|
-
p socket.
|
16
|
+
p socket.connectx(:addresses => addresses, :port => port)
|
17
|
+
p socket.get_status
|
17
18
|
|
18
19
|
# Try a sendv
|
19
20
|
p socket.sendv(:message => ["Hello ", "World!"])
|
data/examples/server_example.rb
CHANGED
@@ -23,7 +23,7 @@ addresses = ['1.1.1.1', '1.1.1.2']
|
|
23
23
|
begin
|
24
24
|
port = 62324
|
25
25
|
socket = SCTP::Socket.new
|
26
|
-
socket.
|
26
|
+
socket.bindx(:port => port, :addresses => addresses)
|
27
27
|
socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4)
|
28
28
|
socket.subscribe(:data_io => true, :shutdown => true, :send_failure => true, :partial_delivery => true)
|
29
29
|
socket.listen
|
data/ext/sctp/extconf.rb
CHANGED
data/ext/sctp/socket.c
CHANGED
@@ -21,6 +21,10 @@ VALUE v_sctp_status_struct;
|
|
21
21
|
VALUE v_sctp_rtoinfo_struct;
|
22
22
|
VALUE v_sctp_associnfo_struct;
|
23
23
|
VALUE v_sctp_default_send_params_struct;
|
24
|
+
VALUE v_sctp_event_subscribe_struct;
|
25
|
+
VALUE v_sctp_receive_info_struct;
|
26
|
+
VALUE v_sctp_peer_addr_params_struct;
|
27
|
+
VALUE v_sender_dry_event_struct;
|
24
28
|
|
25
29
|
#if !defined(IOV_MAX)
|
26
30
|
#if defined(_SC_IOV_MAX)
|
@@ -77,7 +81,7 @@ VALUE rb_hash_aref2(VALUE v_hash, const char* key){
|
|
77
81
|
* socket2 = SCTP::Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
|
78
82
|
*/
|
79
83
|
static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
|
80
|
-
int
|
84
|
+
int fileno;
|
81
85
|
VALUE v_domain, v_type;
|
82
86
|
|
83
87
|
rb_scan_args(argc, argv, "02", &v_domain, &v_type);
|
@@ -88,14 +92,14 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
|
|
88
92
|
if(NIL_P(v_type))
|
89
93
|
v_type = INT2NUM(SOCK_SEQPACKET);
|
90
94
|
|
91
|
-
|
95
|
+
fileno = socket(NUM2INT(v_domain), NUM2INT(v_type), IPPROTO_SCTP);
|
92
96
|
|
93
|
-
if(
|
97
|
+
if(fileno < 0)
|
94
98
|
rb_raise(rb_eSystemCallError, "socket: %s", strerror(errno));
|
95
99
|
|
96
100
|
rb_iv_set(self, "@domain", v_domain);
|
97
101
|
rb_iv_set(self, "@type", v_type);
|
98
|
-
rb_iv_set(self, "@
|
102
|
+
rb_iv_set(self, "@fileno", INT2NUM(fileno));
|
99
103
|
rb_iv_set(self, "@association_id", INT2NUM(0));
|
100
104
|
|
101
105
|
return self;
|
@@ -114,19 +118,19 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
|
|
114
118
|
* socket = SCTP::Socket.new
|
115
119
|
*
|
116
120
|
* # Bind 2 addresses
|
117
|
-
* socket.
|
121
|
+
* socket.bindx(:port => 64325, :addresses => ['10.0.4.5', '10.0.5.5'])
|
118
122
|
*
|
119
123
|
* # Remove 1 later
|
120
|
-
* socket.
|
124
|
+
* socket.bindx(:addresses => ['10.0.4.5'], :flags => SCTP::Socket::BINDX_REM_ADDR)
|
121
125
|
*
|
122
126
|
* If no addresses are specified, then it will bind to all available interfaces. If
|
123
127
|
* no port is specified, then one will be assigned by the host.
|
124
128
|
*
|
125
129
|
* Returns the port that it was bound to.
|
126
130
|
*/
|
127
|
-
static VALUE
|
131
|
+
static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
128
132
|
struct sockaddr_in addrs[8];
|
129
|
-
int i,
|
133
|
+
int i, fileno, num_ip, flags, domain, port;
|
130
134
|
VALUE v_addresses, v_port, v_flags, v_address, v_options;
|
131
135
|
|
132
136
|
rb_scan_args(argc, argv, "01", &v_options);
|
@@ -156,7 +160,7 @@ static VALUE rsctp_bind(int argc, VALUE* argv, VALUE self){
|
|
156
160
|
num_ip = RARRAY_LEN(v_addresses);
|
157
161
|
|
158
162
|
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
159
|
-
|
163
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
160
164
|
|
161
165
|
if(num_ip > 1){
|
162
166
|
for(i = 0; i < num_ip; i++){
|
@@ -172,14 +176,15 @@ static VALUE rsctp_bind(int argc, VALUE* argv, VALUE self){
|
|
172
176
|
addrs[0].sin_addr.s_addr = htonl(INADDR_ANY);
|
173
177
|
}
|
174
178
|
|
175
|
-
if(sctp_bindx(
|
179
|
+
if(sctp_bindx(fileno, (struct sockaddr *) addrs, num_ip, flags) != 0)
|
176
180
|
rb_raise(rb_eSystemCallError, "sctp_bindx: %s", strerror(errno));
|
177
181
|
|
178
182
|
if(port == 0){
|
179
183
|
struct sockaddr_in sin;
|
180
184
|
socklen_t len = sizeof(sin);
|
185
|
+
bzero(&sin, len);
|
181
186
|
|
182
|
-
if(getsockname(
|
187
|
+
if(getsockname(fileno, (struct sockaddr *)&sin, &len) == -1)
|
183
188
|
rb_raise(rb_eSystemCallError, "getsockname: %s", strerror(errno));
|
184
189
|
|
185
190
|
port = sin.sin_port;
|
@@ -197,13 +202,13 @@ static VALUE rsctp_bind(int argc, VALUE* argv, VALUE self){
|
|
197
202
|
* Example:
|
198
203
|
*
|
199
204
|
* socket = SCTP::Socket.new
|
200
|
-
* socket.
|
205
|
+
* socket.connectx(:port => 62354, :addresses => ['10.0.4.5', '10.0.5.5'])
|
201
206
|
*
|
202
207
|
* Note that this will also set/update the object's association_id.
|
203
208
|
*/
|
204
|
-
static VALUE
|
209
|
+
static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
|
205
210
|
struct sockaddr_in addrs[8];
|
206
|
-
int i, num_ip,
|
211
|
+
int i, num_ip, fileno;
|
207
212
|
sctp_assoc_t assoc;
|
208
213
|
VALUE v_address, v_domain, v_options, v_addresses, v_port;
|
209
214
|
|
@@ -235,9 +240,9 @@ static VALUE rsctp_connect(int argc, VALUE* argv, VALUE self){
|
|
235
240
|
addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
|
236
241
|
}
|
237
242
|
|
238
|
-
|
243
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
239
244
|
|
240
|
-
if(sctp_connectx(
|
245
|
+
if(sctp_connectx(fileno, (struct sockaddr *) addrs, num_ip, &assoc) < 0)
|
241
246
|
rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
|
242
247
|
|
243
248
|
rb_iv_set(self, "@association_id", INT2NUM(assoc));
|
@@ -254,30 +259,55 @@ static VALUE rsctp_connect(int argc, VALUE* argv, VALUE self){
|
|
254
259
|
* socket.close
|
255
260
|
*/
|
256
261
|
static VALUE rsctp_close(VALUE self){
|
257
|
-
VALUE
|
262
|
+
VALUE v_fileno = rb_iv_get(self, "@fileno");
|
258
263
|
|
259
|
-
if(close(NUM2INT(
|
264
|
+
if(close(NUM2INT(v_fileno)))
|
260
265
|
rb_raise(rb_eSystemCallError, "close: %s", strerror(errno));
|
261
266
|
|
262
267
|
return self;
|
263
268
|
}
|
264
269
|
|
265
270
|
/*
|
266
|
-
* Return an array of all addresses of a peer
|
271
|
+
* Return an array of all addresses of a peer of the current socket
|
272
|
+
* and association number.
|
273
|
+
*
|
274
|
+
* You may optionally pass a assocation fileno and association ID. Typically
|
275
|
+
* this information would come from the peeloff method.
|
276
|
+
*
|
277
|
+
* Example:
|
278
|
+
*
|
279
|
+
* socket = SCTP::Socket.new
|
280
|
+
* # ...
|
281
|
+
* p socket.getpeernames
|
282
|
+
*
|
283
|
+
* info = socket.recvmsg
|
284
|
+
* association_fileno = socket.peeloff(info.association_id)
|
285
|
+
*
|
286
|
+
* p socket.getpeernames(association_fileno, info.association_id)
|
267
287
|
*/
|
268
|
-
static VALUE rsctp_getpeernames(VALUE self){
|
288
|
+
static VALUE rsctp_getpeernames(int argc, VALUE* argv, VALUE self){
|
269
289
|
sctp_assoc_t assoc_id;
|
270
290
|
struct sockaddr* addrs;
|
271
|
-
int i,
|
291
|
+
int i, fileno, num_addrs;
|
272
292
|
char str[16];
|
293
|
+
VALUE v_fileno, v_association_id;
|
273
294
|
VALUE v_array = rb_ary_new();
|
274
295
|
|
275
296
|
bzero(&addrs, sizeof(addrs));
|
276
297
|
|
277
|
-
|
278
|
-
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
298
|
+
rb_scan_args(argc, argv, "02", &v_fileno, &v_association_id);
|
279
299
|
|
280
|
-
|
300
|
+
if(NIL_P(v_fileno))
|
301
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
302
|
+
else
|
303
|
+
fileno = NUM2INT(v_fileno);
|
304
|
+
|
305
|
+
if(NIL_P(v_association_id))
|
306
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
307
|
+
else
|
308
|
+
assoc_id = NUM2INT(v_association_id);
|
309
|
+
|
310
|
+
num_addrs = sctp_getpaddrs(fileno, assoc_id, &addrs);
|
281
311
|
|
282
312
|
if(num_addrs < 0){
|
283
313
|
sctp_freepaddrs(addrs);
|
@@ -303,20 +333,35 @@ static VALUE rsctp_getpeernames(VALUE self){
|
|
303
333
|
* socket = SCTP::Socket.new
|
304
334
|
* socket.bind(:addresses => ['10.0.4.5', '10.0.5.5'])
|
305
335
|
* socket.getlocalnames # => ['10.0.4.5', '10.0.5.5'])
|
336
|
+
*
|
337
|
+
* # or get info from a peeled off association...
|
338
|
+
*
|
339
|
+
* assoc_fileno = socket.peeloff(some_association_id)
|
340
|
+
* socket.getlocalnames(assoc_fileno, some_association_id)
|
306
341
|
*/
|
307
|
-
static VALUE rsctp_getlocalnames(VALUE self){
|
342
|
+
static VALUE rsctp_getlocalnames(int argc, VALUE* argv, VALUE self){
|
308
343
|
sctp_assoc_t assoc_id;
|
309
344
|
struct sockaddr* addrs;
|
310
|
-
int i,
|
345
|
+
int i, fileno, num_addrs;
|
311
346
|
char str[16];
|
347
|
+
VALUE v_assoc_fileno, v_assoc_id;
|
312
348
|
VALUE v_array = rb_ary_new();
|
313
349
|
|
314
350
|
bzero(&addrs, sizeof(addrs));
|
315
351
|
|
316
|
-
|
317
|
-
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
352
|
+
rb_scan_args(argc, argv, "02", &v_assoc_fileno, &v_assoc_id);
|
318
353
|
|
319
|
-
|
354
|
+
if(NIL_P(v_assoc_fileno))
|
355
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
356
|
+
else
|
357
|
+
fileno = NUM2INT(v_assoc_fileno);
|
358
|
+
|
359
|
+
if(NIL_P(v_assoc_id))
|
360
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
361
|
+
else
|
362
|
+
assoc_id = NUM2INT(v_assoc_id);
|
363
|
+
|
364
|
+
num_addrs = sctp_getladdrs(fileno, assoc_id, &addrs);
|
320
365
|
|
321
366
|
if(num_addrs < 0){
|
322
367
|
sctp_freeladdrs(addrs);
|
@@ -362,7 +407,7 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
362
407
|
struct iovec iov[IOV_MAX];
|
363
408
|
struct sockaddr_in* addrs;
|
364
409
|
struct sctp_sndinfo info;
|
365
|
-
int i,
|
410
|
+
int i, fileno, num_bytes, size, num_ip;
|
366
411
|
|
367
412
|
Check_Type(v_options, T_HASH);
|
368
413
|
|
@@ -385,7 +430,7 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
385
430
|
num_ip = 0;
|
386
431
|
}
|
387
432
|
|
388
|
-
|
433
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
389
434
|
size = RARRAY_LEN(v_message);
|
390
435
|
|
391
436
|
if(!size)
|
@@ -424,7 +469,7 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
424
469
|
}
|
425
470
|
|
426
471
|
num_bytes = sctp_sendv(
|
427
|
-
|
472
|
+
fileno,
|
428
473
|
iov,
|
429
474
|
size,
|
430
475
|
(struct sockaddr*)addrs,
|
@@ -442,6 +487,74 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
442
487
|
}
|
443
488
|
#endif
|
444
489
|
|
490
|
+
#ifdef HAVE_SCTP_RECVV
|
491
|
+
static VALUE rsctp_recvv(int argc, VALUE* argv, VALUE self){
|
492
|
+
VALUE v_flags;
|
493
|
+
int fileno, flags, bytes, on;
|
494
|
+
uint infotype;
|
495
|
+
socklen_t infolen;
|
496
|
+
struct iovec iov[1];
|
497
|
+
struct sctp_rcvinfo info;
|
498
|
+
char buffer[1024];
|
499
|
+
|
500
|
+
bzero(&iov, sizeof(iov));
|
501
|
+
bzero(&info, sizeof(info));
|
502
|
+
bzero(&buffer, sizeof(buffer));
|
503
|
+
|
504
|
+
iov->iov_base = buffer;
|
505
|
+
iov->iov_len = sizeof(buffer);
|
506
|
+
|
507
|
+
rb_scan_args(argc, argv, "01", &v_flags);
|
508
|
+
|
509
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
510
|
+
|
511
|
+
if(NIL_P(v_flags))
|
512
|
+
flags = 0;
|
513
|
+
else
|
514
|
+
flags = NUM2INT(v_flags);
|
515
|
+
|
516
|
+
on = 1;
|
517
|
+
if(setsockopt(fileno, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(on)) < 0)
|
518
|
+
rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
|
519
|
+
|
520
|
+
infolen = sizeof(struct sctp_rcvinfo);
|
521
|
+
infotype = 0;
|
522
|
+
|
523
|
+
bytes = sctp_recvv(
|
524
|
+
fileno,
|
525
|
+
iov,
|
526
|
+
1,
|
527
|
+
NULL,
|
528
|
+
NULL,
|
529
|
+
&info,
|
530
|
+
&infolen,
|
531
|
+
&infotype,
|
532
|
+
&flags
|
533
|
+
);
|
534
|
+
|
535
|
+
if(bytes < 0)
|
536
|
+
rb_raise(rb_eSystemCallError, "sctp_recvv: %s", strerror(errno));
|
537
|
+
|
538
|
+
if(infotype != SCTP_RECVV_RCVINFO){
|
539
|
+
return Qnil;
|
540
|
+
}
|
541
|
+
else{
|
542
|
+
return rb_struct_new(
|
543
|
+
v_sctp_receive_info_struct,
|
544
|
+
rb_str_new2(iov->iov_base),
|
545
|
+
UINT2NUM(info.rcv_sid),
|
546
|
+
UINT2NUM(info.rcv_ssn),
|
547
|
+
UINT2NUM(info.rcv_flags),
|
548
|
+
UINT2NUM(info.rcv_ppid),
|
549
|
+
UINT2NUM(info.rcv_tsn),
|
550
|
+
UINT2NUM(info.rcv_cumtsn),
|
551
|
+
UINT2NUM(info.rcv_context),
|
552
|
+
UINT2NUM(info.rcv_assoc_id)
|
553
|
+
);
|
554
|
+
}
|
555
|
+
}
|
556
|
+
#endif
|
557
|
+
|
445
558
|
/*
|
446
559
|
* Send a message on an already-connected socket to a specific association.
|
447
560
|
*
|
@@ -458,7 +571,7 @@ static VALUE rsctp_send(VALUE self, VALUE v_options){
|
|
458
571
|
uint16_t stream;
|
459
572
|
uint32_t ppid, send_flags, ctrl_flags, ttl, context;
|
460
573
|
ssize_t num_bytes;
|
461
|
-
int
|
574
|
+
int fileno;
|
462
575
|
sctp_assoc_t assoc_id;
|
463
576
|
struct sctp_sndrcvinfo info;
|
464
577
|
VALUE v_msg, v_stream, v_ppid, v_context, v_send_flags, v_ctrl_flags, v_ttl, v_assoc_id;
|
@@ -519,10 +632,10 @@ static VALUE rsctp_send(VALUE self, VALUE v_options){
|
|
519
632
|
info.sinfo_timetolive = ttl;
|
520
633
|
info.sinfo_assoc_id = assoc_id;
|
521
634
|
|
522
|
-
|
635
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
523
636
|
|
524
637
|
num_bytes = sctp_send(
|
525
|
-
|
638
|
+
fileno,
|
526
639
|
StringValueCStr(v_msg),
|
527
640
|
RSTRING_LEN(v_msg),
|
528
641
|
&info,
|
@@ -570,7 +683,7 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
570
683
|
uint32_t ppid, flags, ttl, context;
|
571
684
|
ssize_t num_bytes;
|
572
685
|
struct sockaddr_in addrs[8];
|
573
|
-
int
|
686
|
+
int fileno, size;
|
574
687
|
|
575
688
|
Check_Type(v_options, T_HASH);
|
576
689
|
|
@@ -637,10 +750,10 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
637
750
|
size = 0;
|
638
751
|
}
|
639
752
|
|
640
|
-
|
753
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
641
754
|
|
642
755
|
num_bytes = sctp_sendmsg(
|
643
|
-
|
756
|
+
fileno,
|
644
757
|
StringValueCStr(v_msg),
|
645
758
|
RSTRING_LEN(v_msg),
|
646
759
|
(struct sockaddr*)addrs,
|
@@ -681,7 +794,7 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
681
794
|
VALUE v_flags, v_notification, v_message;
|
682
795
|
struct sctp_sndrcvinfo sndrcvinfo;
|
683
796
|
struct sockaddr_in clientaddr;
|
684
|
-
int flags, bytes,
|
797
|
+
int flags, bytes, fileno;
|
685
798
|
char buffer[1024]; // TODO: Let this be configurable?
|
686
799
|
socklen_t length;
|
687
800
|
|
@@ -692,7 +805,7 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
692
805
|
else
|
693
806
|
flags = NUM2INT(v_flags);
|
694
807
|
|
695
|
-
|
808
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
696
809
|
length = sizeof(struct sockaddr_in);
|
697
810
|
|
698
811
|
bzero(buffer, sizeof(buffer));
|
@@ -700,7 +813,7 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
700
813
|
bzero(&sndrcvinfo, sizeof(sndrcvinfo));
|
701
814
|
|
702
815
|
bytes = sctp_recvmsg(
|
703
|
-
|
816
|
+
fileno,
|
704
817
|
buffer,
|
705
818
|
sizeof(buffer),
|
706
819
|
(struct sockaddr*)&clientaddr,
|
@@ -803,6 +916,7 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
803
916
|
|
804
917
|
v_notification = rb_struct_new(v_remote_error_struct,
|
805
918
|
UINT2NUM(snp->sn_remote_error.sre_type),
|
919
|
+
UINT2NUM(snp->sn_remote_error.sre_flags),
|
806
920
|
UINT2NUM(snp->sn_remote_error.sre_length),
|
807
921
|
UINT2NUM(snp->sn_remote_error.sre_error),
|
808
922
|
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
@@ -884,6 +998,14 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
884
998
|
UINT2NUM(snp->sn_authkey_event.auth_assoc_id)
|
885
999
|
);
|
886
1000
|
break;
|
1001
|
+
case SCTP_SENDER_DRY_EVENT:
|
1002
|
+
v_notification = rb_struct_new(v_sender_dry_event_struct,
|
1003
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_type),
|
1004
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_flags),
|
1005
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_length),
|
1006
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_assoc_id)
|
1007
|
+
);
|
1008
|
+
break;
|
887
1009
|
}
|
888
1010
|
}
|
889
1011
|
|
@@ -915,15 +1037,15 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
915
1037
|
*
|
916
1038
|
* The following parameters can be configured:
|
917
1039
|
*
|
918
|
-
*
|
919
|
-
*
|
920
|
-
*
|
921
|
-
*
|
1040
|
+
* :output_streams - The number of outbound SCTP streams an application would like to request.
|
1041
|
+
* :input_streams - The maximum number of inbound streams an application is prepared to allow.
|
1042
|
+
* :max_attempts - How many times the the SCTP stack should send the initial INIT message before it's considered unreachable.
|
1043
|
+
* :timeout - The maximum RTO value for the INIT timer.
|
922
1044
|
*
|
923
1045
|
* By default these values are set to zero (i.e. ignored).
|
924
1046
|
*/
|
925
1047
|
static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
926
|
-
int
|
1048
|
+
int fileno;
|
927
1049
|
struct sctp_initmsg initmsg;
|
928
1050
|
VALUE v_output, v_input, v_attempts, v_timeout;
|
929
1051
|
|
@@ -934,7 +1056,7 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
934
1056
|
v_attempts = rb_hash_aref2(v_options, "max_attempts");
|
935
1057
|
v_timeout = rb_hash_aref2(v_options, "timeout");
|
936
1058
|
|
937
|
-
|
1059
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
938
1060
|
|
939
1061
|
if(!NIL_P(v_output))
|
940
1062
|
initmsg.sinit_num_ostreams = NUM2INT(v_output);
|
@@ -948,15 +1070,15 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
948
1070
|
if(!NIL_P(v_timeout))
|
949
1071
|
initmsg.sinit_max_init_timeo = NUM2INT(v_timeout);
|
950
1072
|
|
951
|
-
if(setsockopt(
|
1073
|
+
if(setsockopt(fileno, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) < 0)
|
952
1074
|
rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
|
953
1075
|
|
954
1076
|
return self;
|
955
1077
|
}
|
956
1078
|
|
957
1079
|
/*
|
958
|
-
* Subscribe to various notification
|
959
|
-
* data that the socket may receive. The possible notification
|
1080
|
+
* Subscribe to various notification type events, which will generate additional
|
1081
|
+
* data that the socket may receive. The possible notification type events are
|
960
1082
|
* as follows:
|
961
1083
|
*
|
962
1084
|
* :association
|
@@ -979,11 +1101,8 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
979
1101
|
* :adaptation
|
980
1102
|
* :authentication
|
981
1103
|
* :partial_delivery
|
982
|
-
*
|
983
|
-
* Not yet supported:
|
984
|
-
*
|
985
1104
|
* :sender_dry
|
986
|
-
* :peer_error
|
1105
|
+
* :peer_error (aka remote error)
|
987
1106
|
*
|
988
1107
|
* Example:
|
989
1108
|
*
|
@@ -993,11 +1112,13 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
993
1112
|
* socket.subscribe(:data_io => true, :shutdown => true, :send_failure => true)
|
994
1113
|
*/
|
995
1114
|
static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
996
|
-
int
|
1115
|
+
int fileno;
|
997
1116
|
struct sctp_event_subscribe events;
|
998
1117
|
|
999
1118
|
bzero(&events, sizeof(events));
|
1000
|
-
|
1119
|
+
Check_Type(v_options, T_HASH);
|
1120
|
+
|
1121
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1001
1122
|
|
1002
1123
|
if(RTEST(rb_hash_aref2(v_options, "data_io")))
|
1003
1124
|
events.sctp_data_io_event = 1;
|
@@ -1033,7 +1154,7 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
|
1033
1154
|
if(RTEST(rb_hash_aref2(v_options, "sender_dry")))
|
1034
1155
|
events.sctp_sender_dry_event = 1;
|
1035
1156
|
|
1036
|
-
if(setsockopt(
|
1157
|
+
if(setsockopt(fileno, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events)) < 0)
|
1037
1158
|
rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
|
1038
1159
|
|
1039
1160
|
return self;
|
@@ -1044,29 +1165,39 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
|
1044
1165
|
* will be used to accept incoming connection requests.
|
1045
1166
|
*
|
1046
1167
|
* The backlog argument defines the maximum length to which the queue of
|
1047
|
-
* pending connections for sockfd may grow. The default is
|
1168
|
+
* pending connections for sockfd may grow. The default value is 128. The
|
1169
|
+
* maximum value is Socket::SOMAXCONN.
|
1170
|
+
*
|
1171
|
+
* Why a default of 128? The answer is a "best guess" compromise between
|
1172
|
+
* handling server load versus avoiding SYN flood attacks. I leave it as an
|
1173
|
+
* exercise to the programmer to adjust as desired.
|
1174
|
+
*
|
1175
|
+
* See https://tangentsoft.com/wskfaq/advanced.html#backlog if you want
|
1176
|
+
* more details on the advantages and drawbacks of various values.
|
1048
1177
|
*
|
1049
1178
|
* Example:
|
1050
1179
|
*
|
1051
1180
|
* socket = SCTP::Socket.new
|
1052
1181
|
* socket.bind(:port => 62534, :addresses => ['127.0.0.1'])
|
1053
1182
|
* socket.listen
|
1054
|
-
*
|
1055
1183
|
*/
|
1056
1184
|
static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
|
1057
1185
|
VALUE v_backlog;
|
1058
|
-
int backlog,
|
1186
|
+
int backlog, fileno;
|
1059
1187
|
|
1060
1188
|
rb_scan_args(argc, argv, "01", &v_backlog);
|
1061
1189
|
|
1062
1190
|
if(NIL_P(v_backlog))
|
1063
|
-
backlog =
|
1191
|
+
backlog = 128;
|
1064
1192
|
else
|
1065
1193
|
backlog = NUM2INT(v_backlog);
|
1066
1194
|
|
1067
|
-
|
1195
|
+
if(backlog > SOMAXCONN)
|
1196
|
+
rb_raise(rb_eArgError, "backlog value exceeds maximum value of: %i", SOMAXCONN);
|
1197
|
+
|
1198
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1068
1199
|
|
1069
|
-
if(listen(
|
1200
|
+
if(listen(fileno, backlog) < 0)
|
1070
1201
|
rb_raise(rb_eSystemCallError, "listen: %s", strerror(errno));
|
1071
1202
|
|
1072
1203
|
return self;
|
@@ -1074,38 +1205,62 @@ static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
|
|
1074
1205
|
|
1075
1206
|
/*
|
1076
1207
|
* Extracts an association contained by a one-to-many socket connection into
|
1077
|
-
* a one-to-one style socket.
|
1208
|
+
* a one-to-one style socket. Returns the socket descriptor (fileno).
|
1209
|
+
*
|
1210
|
+
* Example:
|
1211
|
+
*
|
1212
|
+
* socket = SCTP::Socket.new
|
1213
|
+
* # etc...
|
1214
|
+
*
|
1215
|
+
* while true
|
1216
|
+
* info = socket.recvmsg
|
1217
|
+
* assoc_fileno = socket.peeloff(info.association_id)
|
1218
|
+
* # ... Do something with this new fileno
|
1219
|
+
* end
|
1078
1220
|
*/
|
1079
1221
|
static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
|
1080
|
-
int
|
1222
|
+
int fileno, assoc_fileno;
|
1081
1223
|
sctp_assoc_t assoc_id;
|
1082
1224
|
|
1083
|
-
|
1225
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1084
1226
|
assoc_id = NUM2INT(v_assoc_id);
|
1085
1227
|
|
1086
|
-
|
1228
|
+
assoc_fileno = sctp_peeloff(fileno, assoc_id);
|
1087
1229
|
|
1088
|
-
if(
|
1230
|
+
if(assoc_fileno < 0)
|
1089
1231
|
rb_raise(rb_eSystemCallError, "sctp_peeloff: %s", strerror(errno));
|
1090
1232
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
return self;
|
1233
|
+
return INT2NUM(assoc_fileno);
|
1094
1234
|
}
|
1095
1235
|
|
1236
|
+
/*
|
1237
|
+
* Returns the default set of parameters that a call to the sendto function
|
1238
|
+
* uses on this association. This is a struct that contains the following
|
1239
|
+
* members:
|
1240
|
+
*
|
1241
|
+
* * stream
|
1242
|
+
* * ssn
|
1243
|
+
* * flags
|
1244
|
+
* * ppid
|
1245
|
+
* * context
|
1246
|
+
* * ttl
|
1247
|
+
* * tsn
|
1248
|
+
* * cumtsn
|
1249
|
+
* * association_id
|
1250
|
+
*/
|
1096
1251
|
static VALUE rsctp_get_default_send_params(VALUE self){
|
1097
|
-
int
|
1252
|
+
int fileno;
|
1098
1253
|
socklen_t size;
|
1099
1254
|
sctp_assoc_t assoc_id;
|
1100
1255
|
struct sctp_sndrcvinfo sndrcv;
|
1101
1256
|
|
1102
1257
|
bzero(&sndrcv, sizeof(sndrcv));
|
1103
1258
|
|
1104
|
-
|
1259
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1105
1260
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1106
1261
|
size = sizeof(struct sctp_sndrcvinfo);
|
1107
1262
|
|
1108
|
-
if(sctp_opt_info(
|
1263
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_DEFAULT_SEND_PARAM, (void*)&sndrcv, &size) < 0)
|
1109
1264
|
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1110
1265
|
|
1111
1266
|
return rb_struct_new(
|
@@ -1122,19 +1277,32 @@ static VALUE rsctp_get_default_send_params(VALUE self){
|
|
1122
1277
|
);
|
1123
1278
|
}
|
1124
1279
|
|
1280
|
+
/*
|
1281
|
+
* Returns the association specific parameters. This is a struct
|
1282
|
+
* that contains the following members:
|
1283
|
+
*
|
1284
|
+
* * association_id
|
1285
|
+
* * max_retransmission_count
|
1286
|
+
* * number_peer_destinations
|
1287
|
+
* * peer_receive_window
|
1288
|
+
* * local_receive_window
|
1289
|
+
* * cookie_life
|
1290
|
+
*
|
1291
|
+
* All values that refer to time values are measured in milliseconds.
|
1292
|
+
*/
|
1125
1293
|
static VALUE rsctp_get_association_info(VALUE self){
|
1126
|
-
int
|
1294
|
+
int fileno;
|
1127
1295
|
socklen_t size;
|
1128
1296
|
sctp_assoc_t assoc_id;
|
1129
1297
|
struct sctp_assocparams assoc;
|
1130
1298
|
|
1131
1299
|
bzero(&assoc, sizeof(assoc));
|
1132
1300
|
|
1133
|
-
|
1301
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1134
1302
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1135
1303
|
size = sizeof(struct sctp_assocparams);
|
1136
1304
|
|
1137
|
-
if(sctp_opt_info(
|
1305
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_ASSOCINFO, (void*)&assoc, &size) < 0)
|
1138
1306
|
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1139
1307
|
|
1140
1308
|
return rb_struct_new(
|
@@ -1148,11 +1316,23 @@ static VALUE rsctp_get_association_info(VALUE self){
|
|
1148
1316
|
);
|
1149
1317
|
}
|
1150
1318
|
|
1319
|
+
/*
|
1320
|
+
* Shuts down socket send and receive operations.
|
1321
|
+
*
|
1322
|
+
* Optionally accepts an argument that specifieds the type of shutdown.
|
1323
|
+
* This can be one of the following values:
|
1324
|
+
*
|
1325
|
+
* * SHUT_RD - Disables further receive operations.
|
1326
|
+
* * SHUT_WR - Disables further send operations.
|
1327
|
+
* * SHUT_RDWR - Disables further send and receive operations.
|
1328
|
+
*
|
1329
|
+
* The default is SHUT_RDWR.
|
1330
|
+
*/
|
1151
1331
|
static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
1152
|
-
int how,
|
1332
|
+
int how, fileno;
|
1153
1333
|
VALUE v_how;
|
1154
1334
|
|
1155
|
-
|
1335
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1156
1336
|
|
1157
1337
|
rb_scan_args(argc, argv, "01", &v_how);
|
1158
1338
|
|
@@ -1164,25 +1344,35 @@ static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
|
1164
1344
|
how = NUM2INT(v_how);
|
1165
1345
|
}
|
1166
1346
|
|
1167
|
-
if(shutdown(
|
1347
|
+
if(shutdown(fileno, how) < 0)
|
1168
1348
|
rb_raise(rb_eSystemCallError, "shutdown: %s", strerror(errno));
|
1169
1349
|
|
1170
1350
|
return self;
|
1171
1351
|
}
|
1172
1352
|
|
1353
|
+
/*
|
1354
|
+
* Returns the protocol parameters that are used to initialize and bind the
|
1355
|
+
* retransmission timeout (RTO) tunable. This is a struct with the following
|
1356
|
+
* members:
|
1357
|
+
*
|
1358
|
+
* * association_id
|
1359
|
+
* * initial
|
1360
|
+
* * max
|
1361
|
+
* * min
|
1362
|
+
*/
|
1173
1363
|
static VALUE rsctp_get_retransmission_info(VALUE self){
|
1174
|
-
int
|
1364
|
+
int fileno;
|
1175
1365
|
socklen_t size;
|
1176
1366
|
sctp_assoc_t assoc_id;
|
1177
1367
|
struct sctp_rtoinfo rto;
|
1178
1368
|
|
1179
1369
|
bzero(&rto, sizeof(rto));
|
1180
1370
|
|
1181
|
-
|
1371
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1182
1372
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1183
1373
|
size = sizeof(struct sctp_rtoinfo);
|
1184
1374
|
|
1185
|
-
if(sctp_opt_info(
|
1375
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_RTOINFO, (void*)&rto, &size) < 0)
|
1186
1376
|
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1187
1377
|
|
1188
1378
|
return rb_struct_new(
|
@@ -1216,7 +1406,7 @@ static VALUE rsctp_get_retransmission_info(VALUE self){
|
|
1216
1406
|
* * primary (IP)
|
1217
1407
|
*/
|
1218
1408
|
static VALUE rsctp_get_status(VALUE self){
|
1219
|
-
int
|
1409
|
+
int fileno;
|
1220
1410
|
socklen_t size;
|
1221
1411
|
sctp_assoc_t assoc_id;
|
1222
1412
|
struct sctp_status status;
|
@@ -1225,11 +1415,11 @@ static VALUE rsctp_get_status(VALUE self){
|
|
1225
1415
|
|
1226
1416
|
bzero(&status, sizeof(status));
|
1227
1417
|
|
1228
|
-
|
1418
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1229
1419
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1230
1420
|
size = sizeof(struct sctp_status);
|
1231
1421
|
|
1232
|
-
if(sctp_opt_info(
|
1422
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_STATUS, (void*)&status, &size) < 0)
|
1233
1423
|
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1234
1424
|
|
1235
1425
|
spinfo = &status.sstat_primary;
|
@@ -1258,6 +1448,87 @@ static VALUE rsctp_get_status(VALUE self){
|
|
1258
1448
|
);
|
1259
1449
|
}
|
1260
1450
|
|
1451
|
+
/*
|
1452
|
+
* Returns a struct of events detailing which events have been
|
1453
|
+
* subscribed to by the socket. The struct contains the following
|
1454
|
+
* members:
|
1455
|
+
*
|
1456
|
+
* * data_io
|
1457
|
+
* * association
|
1458
|
+
* * address
|
1459
|
+
* * send_failure
|
1460
|
+
* * peer_error
|
1461
|
+
* * shutdown
|
1462
|
+
* * partial_delivery
|
1463
|
+
* * adaptation_layer
|
1464
|
+
* * authentication
|
1465
|
+
* * sender_dry
|
1466
|
+
* * stream_reset
|
1467
|
+
* * assoc_reset
|
1468
|
+
* * stream_change
|
1469
|
+
* * send_failure_event
|
1470
|
+
*/
|
1471
|
+
static VALUE rsctp_get_subscriptions(VALUE self){
|
1472
|
+
int fileno;
|
1473
|
+
socklen_t size;
|
1474
|
+
sctp_assoc_t assoc_id;
|
1475
|
+
struct sctp_event_subscribe events;
|
1476
|
+
|
1477
|
+
bzero(&events, sizeof(events));
|
1478
|
+
|
1479
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1480
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1481
|
+
size = sizeof(struct sctp_event_subscribe);
|
1482
|
+
|
1483
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_EVENTS, (void*)&events, &size) < 0)
|
1484
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1485
|
+
|
1486
|
+
return rb_struct_new(v_sctp_event_subscribe_struct,
|
1487
|
+
(events.sctp_data_io_event ? Qtrue : Qfalse),
|
1488
|
+
(events.sctp_association_event ? Qtrue : Qfalse),
|
1489
|
+
(events.sctp_address_event ? Qtrue : Qfalse),
|
1490
|
+
(events.sctp_send_failure_event ? Qtrue : Qfalse),
|
1491
|
+
(events.sctp_peer_error_event ? Qtrue : Qfalse),
|
1492
|
+
(events.sctp_shutdown_event ? Qtrue : Qfalse),
|
1493
|
+
(events.sctp_partial_delivery_event ? Qtrue : Qfalse),
|
1494
|
+
(events.sctp_adaptation_layer_event ? Qtrue : Qfalse),
|
1495
|
+
(events.sctp_authentication_event ? Qtrue : Qfalse),
|
1496
|
+
(events.sctp_sender_dry_event ? Qtrue : Qfalse),
|
1497
|
+
(events.sctp_stream_reset_event ? Qtrue : Qfalse),
|
1498
|
+
(events.sctp_assoc_reset_event ? Qtrue : Qfalse),
|
1499
|
+
(events.sctp_stream_change_event ? Qtrue : Qfalse),
|
1500
|
+
(events.sctp_send_failure_event_event ? Qtrue : Qfalse)
|
1501
|
+
);
|
1502
|
+
}
|
1503
|
+
|
1504
|
+
static VALUE rsctp_get_peer_address_params(VALUE self){
|
1505
|
+
int fileno;
|
1506
|
+
char str[16];
|
1507
|
+
socklen_t size;
|
1508
|
+
sctp_assoc_t assoc_id;
|
1509
|
+
struct sctp_paddrparams paddr;
|
1510
|
+
|
1511
|
+
bzero(&paddr, sizeof(paddr));
|
1512
|
+
bzero(&str, sizeof(str));
|
1513
|
+
|
1514
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1515
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1516
|
+
size = sizeof(struct sctp_paddrparams);
|
1517
|
+
|
1518
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_PEER_ADDR_PARAMS, (void*)&paddr, &size) < 0)
|
1519
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1520
|
+
|
1521
|
+
inet_ntop(AF_INET, ((struct sockaddr_in*)&paddr.spp_address), str, sizeof(str));
|
1522
|
+
|
1523
|
+
return rb_struct_new(
|
1524
|
+
v_sctp_peer_addr_params_struct,
|
1525
|
+
INT2NUM(paddr.spp_assoc_id),
|
1526
|
+
rb_str_new2(str),
|
1527
|
+
INT2NUM(paddr.spp_hbinterval),
|
1528
|
+
INT2NUM(paddr.spp_pathmaxrxt)
|
1529
|
+
);
|
1530
|
+
}
|
1531
|
+
|
1261
1532
|
void Init_socket(void){
|
1262
1533
|
mSCTP = rb_define_module("SCTP");
|
1263
1534
|
cSocket = rb_define_class_under(mSCTP, "Socket", rb_cObject);
|
@@ -1278,7 +1549,7 @@ void Init_socket(void){
|
|
1278
1549
|
);
|
1279
1550
|
|
1280
1551
|
v_remote_error_struct = rb_struct_define(
|
1281
|
-
"RemoteError", "type", "length", "error", "association_id", "data", NULL
|
1552
|
+
"RemoteError", "type", "flags", "length", "error", "association_id", "data", NULL
|
1282
1553
|
);
|
1283
1554
|
|
1284
1555
|
v_send_failed_event_struct = rb_struct_define(
|
@@ -1306,6 +1577,10 @@ void Init_socket(void){
|
|
1306
1577
|
"AuthEvent", "type", "length", "key_number", "indication", "association_id", NULL
|
1307
1578
|
);
|
1308
1579
|
|
1580
|
+
v_sender_dry_event_struct = rb_struct_define(
|
1581
|
+
"SenderDryEvent", "type", "flags", "length", "association_id", NULL
|
1582
|
+
);
|
1583
|
+
|
1309
1584
|
v_sockaddr_in_struct = rb_struct_define(
|
1310
1585
|
"SockAddrIn", "family", "port", "address", NULL
|
1311
1586
|
);
|
@@ -1330,19 +1605,38 @@ void Init_socket(void){
|
|
1330
1605
|
"ttl", "tsn", "cumtsn", "association_id", NULL
|
1331
1606
|
);
|
1332
1607
|
|
1608
|
+
v_sctp_event_subscribe_struct = rb_struct_define(
|
1609
|
+
"EventSubscriptions", "data_io", "association", "address", "send_failure",
|
1610
|
+
"peer_error", "shutdown", "partial_delivery", "adaptation_layer",
|
1611
|
+
"authentication", "sender_dry", "stream_reset", "assoc_reset",
|
1612
|
+
"stream_change", "send_failure_event", NULL
|
1613
|
+
);
|
1614
|
+
|
1615
|
+
v_sctp_receive_info_struct = rb_struct_define(
|
1616
|
+
"ReceiveInfo", "message", "sid", "ssn", "flags", "ppid", "tsn",
|
1617
|
+
"cumtsn", "context", "assocation_id", NULL
|
1618
|
+
);
|
1619
|
+
|
1620
|
+
v_sctp_peer_addr_params_struct = rb_struct_define(
|
1621
|
+
"PeerAddressParams", "association_id", "address", "heartbeat_interval",
|
1622
|
+
"max_retransmission_count", NULL
|
1623
|
+
);
|
1624
|
+
|
1333
1625
|
rb_define_method(cSocket, "initialize", rsctp_init, -1);
|
1334
1626
|
|
1335
|
-
rb_define_method(cSocket, "
|
1627
|
+
rb_define_method(cSocket, "bindx", rsctp_bindx, -1);
|
1336
1628
|
rb_define_method(cSocket, "close", rsctp_close, 0);
|
1337
|
-
rb_define_method(cSocket, "
|
1338
|
-
rb_define_method(cSocket, "getpeernames", rsctp_getpeernames,
|
1339
|
-
rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames,
|
1629
|
+
rb_define_method(cSocket, "connectx", rsctp_connectx, -1);
|
1630
|
+
rb_define_method(cSocket, "getpeernames", rsctp_getpeernames, -1);
|
1631
|
+
rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames, -1);
|
1340
1632
|
rb_define_method(cSocket, "get_status", rsctp_get_status, 0);
|
1341
1633
|
rb_define_method(cSocket, "get_default_send_params", rsctp_get_default_send_params, 0);
|
1342
1634
|
rb_define_method(cSocket, "get_retransmission_info", rsctp_get_retransmission_info, 0);
|
1343
1635
|
rb_define_method(cSocket, "get_association_info", rsctp_get_association_info, 0);
|
1636
|
+
rb_define_method(cSocket, "get_subscriptions", rsctp_get_subscriptions, 0);
|
1637
|
+
rb_define_method(cSocket, "get_peer_address_params", rsctp_get_peer_address_params, 0);
|
1344
1638
|
rb_define_method(cSocket, "listen", rsctp_listen, -1);
|
1345
|
-
rb_define_method(cSocket, "peeloff
|
1639
|
+
rb_define_method(cSocket, "peeloff", rsctp_peeloff, 1);
|
1346
1640
|
rb_define_method(cSocket, "recvmsg", rsctp_recvmsg, -1);
|
1347
1641
|
rb_define_method(cSocket, "send", rsctp_send, 1);
|
1348
1642
|
|
@@ -1350,6 +1644,10 @@ void Init_socket(void){
|
|
1350
1644
|
rb_define_method(cSocket, "sendv", rsctp_sendv, 1);
|
1351
1645
|
#endif
|
1352
1646
|
|
1647
|
+
#ifdef HAVE_SCTP_RECVV
|
1648
|
+
rb_define_method(cSocket, "recvv", rsctp_recvv, -1);
|
1649
|
+
#endif
|
1650
|
+
|
1353
1651
|
rb_define_method(cSocket, "sendmsg", rsctp_sendmsg, 1);
|
1354
1652
|
rb_define_method(cSocket, "set_initmsg", rsctp_set_initmsg, 1);
|
1355
1653
|
rb_define_method(cSocket, "shutdown", rsctp_shutdown, -1);
|
@@ -1357,12 +1655,12 @@ void Init_socket(void){
|
|
1357
1655
|
|
1358
1656
|
rb_define_attr(cSocket, "domain", 1, 1);
|
1359
1657
|
rb_define_attr(cSocket, "type", 1, 1);
|
1360
|
-
rb_define_attr(cSocket, "
|
1658
|
+
rb_define_attr(cSocket, "fileno", 1, 1);
|
1361
1659
|
rb_define_attr(cSocket, "association_id", 1, 1);
|
1362
1660
|
rb_define_attr(cSocket, "port", 1, 1);
|
1363
1661
|
|
1364
|
-
/* 0.0
|
1365
|
-
rb_define_const(cSocket, "VERSION", rb_str_new2("0.0
|
1662
|
+
/* 0.1.0: The version of this library */
|
1663
|
+
rb_define_const(cSocket, "VERSION", rb_str_new2("0.1.0"));
|
1366
1664
|
|
1367
1665
|
/* send flags */
|
1368
1666
|
|
data/sctp-socket.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'sctp-socket'
|
3
|
-
spec.version = '0.0
|
3
|
+
spec.version = '0.1.0'
|
4
4
|
spec.author = 'Daniel Berger'
|
5
5
|
spec.email = 'djberg96@gmail.com'
|
6
6
|
spec.summary = 'Ruby bindings for SCTP sockets'
|
@@ -14,10 +14,10 @@ Gem::Specification.new do |spec|
|
|
14
14
|
|
15
15
|
spec.extensions = ['ext/sctp/extconf.rb']
|
16
16
|
|
17
|
-
spec.add_development_dependency 'bundler'
|
18
|
-
spec.add_development_dependency 'rake'
|
19
|
-
spec.add_development_dependency 'rake-compiler'
|
20
|
-
spec.add_development_dependency 'rspec'
|
17
|
+
spec.add_development_dependency 'bundler'
|
18
|
+
spec.add_development_dependency 'rake'
|
19
|
+
spec.add_development_dependency 'rake-compiler'
|
20
|
+
spec.add_development_dependency 'rspec'
|
21
21
|
|
22
22
|
spec.metadata = {
|
23
23
|
'homepage_uri' => 'https://github.com/djberg96/sctp-socket',
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Berger
|
@@ -35,64 +35,64 @@ cert_chain:
|
|
35
35
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
36
36
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2024-
|
38
|
+
date: 2024-06-01 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: '0'
|
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: '0'
|
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: '
|
60
|
+
version: '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: '
|
67
|
+
version: '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: '0'
|
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: '0'
|
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: '0'
|
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: '
|
95
|
+
version: '0'
|
96
96
|
description: |2
|
97
97
|
The sctp-socket library provides Ruby bindings for SCTP sockets. is a
|
98
98
|
message oriented, reliable transport protocol with direct support for
|
metadata.gz.sig
CHANGED
Binary file
|