sctp-socket 0.0.7 → 0.1.1
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 +3 -3
- data/.github/workflows/ruby.yml +37 -0
- data/CHANGES.md +20 -0
- data/README.md +13 -3
- data/Rakefile +11 -0
- data/ext/sctp/socket.c +891 -227
- data/sctp-socket.gemspec +7 -6
- data.tar.gz.sig +0 -0
- metadata +21 -19
- metadata.gz.sig +0 -0
data/ext/sctp/socket.c
CHANGED
@@ -23,6 +23,9 @@ VALUE v_sctp_associnfo_struct;
|
|
23
23
|
VALUE v_sctp_default_send_params_struct;
|
24
24
|
VALUE v_sctp_event_subscribe_struct;
|
25
25
|
VALUE v_sctp_receive_info_struct;
|
26
|
+
VALUE v_sctp_peer_addr_params_struct;
|
27
|
+
VALUE v_sender_dry_event_struct;
|
28
|
+
VALUE v_sctp_initmsg_struct;
|
26
29
|
|
27
30
|
#if !defined(IOV_MAX)
|
28
31
|
#if defined(_SC_IOV_MAX)
|
@@ -61,7 +64,195 @@ VALUE rb_hash_aref2(VALUE v_hash, const char* key){
|
|
61
64
|
return v_val;
|
62
65
|
}
|
63
66
|
|
67
|
+
VALUE get_notification_info(char* buffer){
|
68
|
+
uint32_t i;
|
69
|
+
char str[16];
|
70
|
+
union sctp_notification* snp;
|
71
|
+
VALUE v_notification = Qnil;
|
72
|
+
VALUE v_str = Qnil;
|
73
|
+
VALUE* v_temp;
|
74
|
+
|
75
|
+
snp = (union sctp_notification*)buffer;
|
76
|
+
|
77
|
+
switch(snp->sn_header.sn_type){
|
78
|
+
case SCTP_ASSOC_CHANGE:
|
79
|
+
switch(snp->sn_assoc_change.sac_state){
|
80
|
+
case SCTP_COMM_LOST:
|
81
|
+
v_str = rb_str_new2("comm lost");
|
82
|
+
break;
|
83
|
+
case SCTP_COMM_UP:
|
84
|
+
v_str = rb_str_new2("comm up");
|
85
|
+
break;
|
86
|
+
case SCTP_RESTART:
|
87
|
+
v_str = rb_str_new2("restart");
|
88
|
+
break;
|
89
|
+
case SCTP_SHUTDOWN_COMP:
|
90
|
+
v_str = rb_str_new2("shutdown complete");
|
91
|
+
break;
|
92
|
+
case SCTP_CANT_STR_ASSOC:
|
93
|
+
v_str = rb_str_new2("association setup failed");
|
94
|
+
break;
|
95
|
+
default:
|
96
|
+
v_str = rb_str_new2("unknown");
|
97
|
+
}
|
98
|
+
|
99
|
+
v_notification = rb_struct_new(v_assoc_change_struct,
|
100
|
+
UINT2NUM(snp->sn_assoc_change.sac_type),
|
101
|
+
UINT2NUM(snp->sn_assoc_change.sac_length),
|
102
|
+
UINT2NUM(snp->sn_assoc_change.sac_state),
|
103
|
+
UINT2NUM(snp->sn_assoc_change.sac_error),
|
104
|
+
UINT2NUM(snp->sn_assoc_change.sac_outbound_streams),
|
105
|
+
UINT2NUM(snp->sn_assoc_change.sac_inbound_streams),
|
106
|
+
UINT2NUM(snp->sn_assoc_change.sac_assoc_id),
|
107
|
+
v_str
|
108
|
+
);
|
109
|
+
break;
|
110
|
+
case SCTP_PEER_ADDR_CHANGE:
|
111
|
+
switch(snp->sn_paddr_change.spc_state){
|
112
|
+
case SCTP_ADDR_AVAILABLE:
|
113
|
+
v_str = rb_str_new2("available");
|
114
|
+
break;
|
115
|
+
case SCTP_ADDR_UNREACHABLE:
|
116
|
+
v_str = rb_str_new2("unreachable");
|
117
|
+
break;
|
118
|
+
case SCTP_ADDR_REMOVED:
|
119
|
+
v_str = rb_str_new2("removed from association");
|
120
|
+
break;
|
121
|
+
case SCTP_ADDR_ADDED:
|
122
|
+
v_str = rb_str_new2("added to association");
|
123
|
+
break;
|
124
|
+
case SCTP_ADDR_MADE_PRIM:
|
125
|
+
v_str = rb_str_new2("primary destination");
|
126
|
+
break;
|
127
|
+
default:
|
128
|
+
v_str = rb_str_new2("unknown");
|
129
|
+
}
|
130
|
+
|
131
|
+
inet_ntop(
|
132
|
+
((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_family,
|
133
|
+
&(((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_addr),
|
134
|
+
str,
|
135
|
+
sizeof(str)
|
136
|
+
);
|
137
|
+
|
138
|
+
v_notification = rb_struct_new(v_peeraddr_change_struct,
|
139
|
+
UINT2NUM(snp->sn_paddr_change.spc_type),
|
140
|
+
UINT2NUM(snp->sn_paddr_change.spc_length),
|
141
|
+
rb_str_new2(str),
|
142
|
+
UINT2NUM(snp->sn_paddr_change.spc_state),
|
143
|
+
UINT2NUM(snp->sn_paddr_change.spc_error),
|
144
|
+
UINT2NUM(snp->sn_paddr_change.spc_assoc_id),
|
145
|
+
v_str
|
146
|
+
);
|
147
|
+
break;
|
148
|
+
case SCTP_REMOTE_ERROR:
|
149
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_remote_error.sre_length);
|
150
|
+
|
151
|
+
for(i = 0; i < snp->sn_remote_error.sre_length; i++){
|
152
|
+
v_temp[i] = UINT2NUM(snp->sn_remote_error.sre_data[i]);
|
153
|
+
}
|
154
|
+
|
155
|
+
v_notification = rb_struct_new(v_remote_error_struct,
|
156
|
+
UINT2NUM(snp->sn_remote_error.sre_type),
|
157
|
+
UINT2NUM(snp->sn_remote_error.sre_flags),
|
158
|
+
UINT2NUM(snp->sn_remote_error.sre_length),
|
159
|
+
UINT2NUM(snp->sn_remote_error.sre_error),
|
160
|
+
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
161
|
+
rb_ary_new4(snp->sn_remote_error.sre_length, v_temp)
|
162
|
+
);
|
163
|
+
break;
|
164
|
+
#ifdef SCTP_SEND_FAILED_EVENT
|
165
|
+
case SCTP_SEND_FAILED_EVENT:
|
166
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed_event.ssf_length);
|
167
|
+
|
168
|
+
for(i = 0; i < snp->sn_send_failed_event.ssf_length; i++){
|
169
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssf_data[i]);
|
170
|
+
}
|
171
|
+
|
172
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
173
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_type),
|
174
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_length),
|
175
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_error),
|
176
|
+
rb_struct_new(v_sndinfo_struct,
|
177
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
|
178
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
|
179
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
|
180
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
|
181
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
|
182
|
+
),
|
183
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_assoc_id),
|
184
|
+
rb_ary_new4(snp->sn_send_failed_event.ssf_length, v_temp)
|
185
|
+
);
|
186
|
+
break;
|
187
|
+
#else
|
188
|
+
case SCTP_SEND_FAILED:
|
189
|
+
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed.ssf_length);
|
190
|
+
|
191
|
+
for(i = 0; i < snp->sn_send_failed.ssf_length; i++){
|
192
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed.ssf_data[i]);
|
193
|
+
}
|
194
|
+
|
195
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
196
|
+
UINT2NUM(snp->sn_send_failed.ssf_type),
|
197
|
+
UINT2NUM(snp->sn_send_failed.ssf_length),
|
198
|
+
UINT2NUM(snp->sn_send_failed.ssf_error),
|
199
|
+
Qnil,
|
200
|
+
UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
|
201
|
+
rb_ary_new4(snp->sn_send_failed.ssf_length, v_temp)
|
202
|
+
);
|
203
|
+
break;
|
204
|
+
#endif
|
205
|
+
case SCTP_SHUTDOWN_EVENT:
|
206
|
+
v_notification = rb_struct_new(v_shutdown_event_struct,
|
207
|
+
UINT2NUM(snp->sn_shutdown_event.sse_type),
|
208
|
+
UINT2NUM(snp->sn_shutdown_event.sse_length),
|
209
|
+
UINT2NUM(snp->sn_shutdown_event.sse_assoc_id)
|
210
|
+
);
|
211
|
+
break;
|
212
|
+
case SCTP_ADAPTATION_INDICATION:
|
213
|
+
v_notification = rb_struct_new(v_adaptation_event_struct,
|
214
|
+
UINT2NUM(snp->sn_adaptation_event.sai_type),
|
215
|
+
UINT2NUM(snp->sn_adaptation_event.sai_length),
|
216
|
+
UINT2NUM(snp->sn_adaptation_event.sai_adaptation_ind),
|
217
|
+
UINT2NUM(snp->sn_adaptation_event.sai_assoc_id)
|
218
|
+
);
|
219
|
+
break;
|
220
|
+
case SCTP_PARTIAL_DELIVERY_EVENT:
|
221
|
+
v_notification = rb_struct_new(v_partial_delivery_event_struct,
|
222
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_type),
|
223
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_length),
|
224
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_indication),
|
225
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_stream),
|
226
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_seq),
|
227
|
+
UINT2NUM(snp->sn_pdapi_event.pdapi_assoc_id)
|
228
|
+
);
|
229
|
+
break;
|
230
|
+
case SCTP_AUTHENTICATION_EVENT:
|
231
|
+
v_notification = rb_struct_new(v_auth_event_struct,
|
232
|
+
UINT2NUM(snp->sn_authkey_event.auth_type),
|
233
|
+
UINT2NUM(snp->sn_authkey_event.auth_length),
|
234
|
+
UINT2NUM(snp->sn_authkey_event.auth_keynumber),
|
235
|
+
UINT2NUM(snp->sn_authkey_event.auth_indication),
|
236
|
+
UINT2NUM(snp->sn_authkey_event.auth_assoc_id)
|
237
|
+
);
|
238
|
+
break;
|
239
|
+
case SCTP_SENDER_DRY_EVENT:
|
240
|
+
v_notification = rb_struct_new(v_sender_dry_event_struct,
|
241
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_type),
|
242
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_flags),
|
243
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_length),
|
244
|
+
UINT2NUM(snp->sn_sender_dry_event.sender_dry_assoc_id)
|
245
|
+
);
|
246
|
+
break;
|
247
|
+
}
|
248
|
+
|
249
|
+
return v_notification;
|
250
|
+
}
|
251
|
+
|
64
252
|
/*
|
253
|
+
* call-seq:
|
254
|
+
* SCTP::Socket.new(domain = Socket::AF_INET, type = Socket::SOCK_STREAM)
|
255
|
+
*
|
65
256
|
* Create and return a new SCTP::Socket instance. You may optionally pass in
|
66
257
|
* a domain (aka family) value and socket type. By default these are AF_INET
|
67
258
|
* and SOCK_SEQPACKET, respectively.
|
@@ -104,27 +295,30 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
|
|
104
295
|
}
|
105
296
|
|
106
297
|
/*
|
107
|
-
*
|
108
|
-
*
|
298
|
+
* call-seq:
|
299
|
+
* SCTP::Socket#bindx(options)
|
109
300
|
*
|
110
|
-
*
|
111
|
-
*
|
112
|
-
* respectively.
|
301
|
+
* Bind a subset of IP addresses associated with the host system on the
|
302
|
+
* given port, or a port assigned by the operating system if none is provided.
|
113
303
|
*
|
114
|
-
*
|
304
|
+
* Note that you can both add or remove an address to or from the socket
|
305
|
+
* using the SCTP_BINDX_ADD_ADDR (default) or SCTP_BINDX_REM_ADDR constants,
|
306
|
+
* respectively.
|
115
307
|
*
|
116
|
-
*
|
308
|
+
* Example:
|
117
309
|
*
|
118
|
-
*
|
119
|
-
* socket.bindx(:port => 64325, :addresses => ['10.0.4.5', '10.0.5.5'])
|
310
|
+
* socket = SCTP::Socket.new
|
120
311
|
*
|
121
|
-
*
|
122
|
-
*
|
312
|
+
* # Bind 2 addresses
|
313
|
+
* socket.bindx(:port => 64325, :addresses => ['10.0.4.5', '10.0.5.5'])
|
123
314
|
*
|
124
|
-
*
|
125
|
-
*
|
315
|
+
* # Remove 1 later
|
316
|
+
* socket.bindx(:addresses => ['10.0.4.5'], :flags => SCTP::Socket::BINDX_REM_ADDR)
|
126
317
|
*
|
127
|
-
*
|
318
|
+
* If no addresses are specified, then it will bind to all available interfaces. If
|
319
|
+
* no port is specified, then one will be assigned by the host.
|
320
|
+
*
|
321
|
+
* Returns the port that it was bound to.
|
128
322
|
*/
|
129
323
|
static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
130
324
|
struct sockaddr_in addrs[8];
|
@@ -180,6 +374,7 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
180
374
|
if(port == 0){
|
181
375
|
struct sockaddr_in sin;
|
182
376
|
socklen_t len = sizeof(sin);
|
377
|
+
bzero(&sin, len);
|
183
378
|
|
184
379
|
if(getsockname(fileno, (struct sockaddr *)&sin, &len) == -1)
|
185
380
|
rb_raise(rb_eSystemCallError, "getsockname: %s", strerror(errno));
|
@@ -193,6 +388,9 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
193
388
|
}
|
194
389
|
|
195
390
|
/*
|
391
|
+
* call-seq:
|
392
|
+
* SCTP::Socket#connectx(options)
|
393
|
+
*
|
196
394
|
* Connect the socket to a multihomed peer via the provided array of addresses
|
197
395
|
* using the domain specified in the constructor. You must also specify the port.
|
198
396
|
*
|
@@ -201,7 +399,9 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
201
399
|
* socket = SCTP::Socket.new
|
202
400
|
* socket.connectx(:port => 62354, :addresses => ['10.0.4.5', '10.0.5.5'])
|
203
401
|
*
|
204
|
-
* Note that this will also set/update the object's association_id.
|
402
|
+
* Note that this will also set/update the object's association_id. Also note that
|
403
|
+
* this method is not strictly necessary on the client side, since the various send
|
404
|
+
* methods will automatically establish associations.
|
205
405
|
*/
|
206
406
|
static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
|
207
407
|
struct sockaddr_in addrs[8];
|
@@ -248,6 +448,9 @@ static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
|
|
248
448
|
}
|
249
449
|
|
250
450
|
/*
|
451
|
+
* call-seq:
|
452
|
+
* SCTP::Socket#close
|
453
|
+
*
|
251
454
|
* Close the socket. You should always do this.
|
252
455
|
*
|
253
456
|
* Example:
|
@@ -265,22 +468,25 @@ static VALUE rsctp_close(VALUE self){
|
|
265
468
|
}
|
266
469
|
|
267
470
|
/*
|
268
|
-
*
|
269
|
-
*
|
471
|
+
* call-seq:
|
472
|
+
* SCTP::Socket#getpeernames
|
270
473
|
*
|
271
|
-
*
|
272
|
-
*
|
474
|
+
* Return an array of all addresses of a peer of the current socket
|
475
|
+
* and association number.
|
273
476
|
*
|
274
|
-
*
|
477
|
+
* You may optionally pass a assocation fileno and association ID. Typically
|
478
|
+
* this information would come from the peeloff method.
|
275
479
|
*
|
276
|
-
*
|
277
|
-
* # ...
|
278
|
-
* p socket.getpeernames
|
480
|
+
* Example:
|
279
481
|
*
|
280
|
-
*
|
281
|
-
*
|
482
|
+
* socket = SCTP::Socket.new
|
483
|
+
* # ...
|
484
|
+
* p socket.getpeernames
|
485
|
+
*
|
486
|
+
* info = socket.recvmsg
|
487
|
+
* association_fileno = socket.peeloff(info.association_id)
|
282
488
|
*
|
283
|
-
*
|
489
|
+
* p socket.getpeernames(association_fileno, info.association_id)
|
284
490
|
*/
|
285
491
|
static VALUE rsctp_getpeernames(int argc, VALUE* argv, VALUE self){
|
286
492
|
sctp_assoc_t assoc_id;
|
@@ -323,6 +529,9 @@ static VALUE rsctp_getpeernames(int argc, VALUE* argv, VALUE self){
|
|
323
529
|
}
|
324
530
|
|
325
531
|
/*
|
532
|
+
* call-seq:
|
533
|
+
* SCTP::Socket#getlocalnames
|
534
|
+
*
|
326
535
|
* Return an array of local addresses that are part of the association.
|
327
536
|
*
|
328
537
|
* Example:
|
@@ -378,6 +587,9 @@ static VALUE rsctp_getlocalnames(int argc, VALUE* argv, VALUE self){
|
|
378
587
|
|
379
588
|
#ifdef HAVE_SCTP_SENDV
|
380
589
|
/*
|
590
|
+
* call-seq:
|
591
|
+
* SCTP::Socket#sendv(options)
|
592
|
+
*
|
381
593
|
* Transmit a message to an SCTP endpoint using a gather-write. The following
|
382
594
|
* hash of options is permitted:
|
383
595
|
*
|
@@ -389,13 +601,14 @@ static VALUE rsctp_getlocalnames(int argc, VALUE* argv, VALUE self){
|
|
389
601
|
*
|
390
602
|
* socket = SCTP::Socket.new
|
391
603
|
*
|
604
|
+
* # You can specify addresses here or in an earlier connectx call.
|
392
605
|
* socket.sendv
|
393
606
|
* :message => ['Hello ', 'World.'],
|
394
607
|
* :addresses => ['10.0.5.4', '10.0.6.4'],
|
395
608
|
* :info_type => SCTP::Socket:::SCTP_SENDV_SNDINFO
|
396
609
|
* )
|
397
610
|
*
|
398
|
-
* CAVEAT: Currently
|
611
|
+
* CAVEAT: Currently info_type is not yet supported.
|
399
612
|
*
|
400
613
|
* Returns the number of bytes sent.
|
401
614
|
*/
|
@@ -403,13 +616,13 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
403
616
|
VALUE v_msg, v_message, v_addresses;
|
404
617
|
struct iovec iov[IOV_MAX];
|
405
618
|
struct sockaddr_in* addrs;
|
406
|
-
struct
|
619
|
+
struct sctp_sendv_spa spa;
|
407
620
|
int i, fileno, num_bytes, size, num_ip;
|
408
621
|
|
409
622
|
Check_Type(v_options, T_HASH);
|
410
623
|
|
411
624
|
bzero(&iov, sizeof(iov));
|
412
|
-
bzero(&
|
625
|
+
bzero(&spa, sizeof(spa));
|
413
626
|
|
414
627
|
v_message = rb_hash_aref2(v_options, "message");
|
415
628
|
v_addresses = rb_hash_aref2(v_options, "addresses");
|
@@ -420,7 +633,7 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
420
633
|
if(!NIL_P(v_addresses)){
|
421
634
|
Check_Type(v_addresses, T_ARRAY);
|
422
635
|
num_ip = RARRAY_LEN(v_addresses);
|
423
|
-
addrs = (struct sockaddr_in*)alloca(sizeof(
|
636
|
+
addrs = (struct sockaddr_in*)alloca(num_ip * sizeof(*addrs));
|
424
637
|
}
|
425
638
|
else{
|
426
639
|
addrs = NULL;
|
@@ -436,26 +649,28 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
436
649
|
if(size > IOV_MAX)
|
437
650
|
rb_raise(rb_eArgError, "Array size is greater than IOV_MAX");
|
438
651
|
|
439
|
-
|
440
|
-
|
652
|
+
// TODO: Make this configurable
|
653
|
+
spa.sendv_sndinfo.snd_flags = SCTP_UNORDERED;
|
654
|
+
spa.sendv_sndinfo.snd_assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
441
655
|
|
442
656
|
if(!NIL_P(v_addresses)){
|
443
|
-
int i, port;
|
657
|
+
int i, port, domain;
|
444
658
|
VALUE v_address, v_port;
|
445
659
|
|
446
|
-
v_port =
|
660
|
+
v_port = rb_iv_get(self, "@port");
|
447
661
|
|
448
662
|
if(NIL_P(v_port))
|
449
663
|
port = 0;
|
450
664
|
else
|
451
665
|
port = NUM2INT(v_port);
|
452
666
|
|
667
|
+
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
668
|
+
|
453
669
|
for(i = 0; i < num_ip; i++){
|
454
670
|
v_address = RARRAY_PTR(v_addresses)[i];
|
455
|
-
addrs
|
456
|
-
addrs
|
457
|
-
addrs
|
458
|
-
addrs += sizeof(struct sockaddr_in);
|
671
|
+
addrs[i].sin_family = domain;
|
672
|
+
addrs[i].sin_port = htons(port);
|
673
|
+
addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
|
459
674
|
}
|
460
675
|
}
|
461
676
|
|
@@ -471,9 +686,9 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
471
686
|
size,
|
472
687
|
(struct sockaddr*)addrs,
|
473
688
|
num_ip,
|
474
|
-
&
|
475
|
-
sizeof(
|
476
|
-
|
689
|
+
&spa,
|
690
|
+
sizeof(spa),
|
691
|
+
SCTP_SENDV_SPA,
|
477
692
|
0
|
478
693
|
);
|
479
694
|
|
@@ -553,6 +768,9 @@ static VALUE rsctp_recvv(int argc, VALUE* argv, VALUE self){
|
|
553
768
|
#endif
|
554
769
|
|
555
770
|
/*
|
771
|
+
* call-seq:
|
772
|
+
* SCTP::Socket.send(options)
|
773
|
+
*
|
556
774
|
* Send a message on an already-connected socket to a specific association.
|
557
775
|
*
|
558
776
|
* Example:
|
@@ -646,6 +864,9 @@ static VALUE rsctp_send(VALUE self, VALUE v_options){
|
|
646
864
|
}
|
647
865
|
|
648
866
|
/*
|
867
|
+
* call-seq:
|
868
|
+
* SCTP::Socket#sendmsg(options)
|
869
|
+
*
|
649
870
|
* Transmit a message to an SCTP endpoint. The following hash of options
|
650
871
|
* is permitted:
|
651
872
|
*
|
@@ -769,6 +990,9 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
769
990
|
}
|
770
991
|
|
771
992
|
/*
|
993
|
+
* call-seq:
|
994
|
+
* SCTP::Socket#recvmsg(flags=0)
|
995
|
+
*
|
772
996
|
* Receive a message from another SCTP endpoint.
|
773
997
|
*
|
774
998
|
* Example:
|
@@ -824,178 +1048,8 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
824
1048
|
|
825
1049
|
v_notification = Qnil;
|
826
1050
|
|
827
|
-
if(flags & MSG_NOTIFICATION)
|
828
|
-
|
829
|
-
char str[16];
|
830
|
-
union sctp_notification* snp;
|
831
|
-
VALUE v_str;
|
832
|
-
VALUE* v_temp;
|
833
|
-
|
834
|
-
snp = (union sctp_notification*)buffer;
|
835
|
-
|
836
|
-
switch(snp->sn_header.sn_type){
|
837
|
-
case SCTP_ASSOC_CHANGE:
|
838
|
-
switch(snp->sn_assoc_change.sac_state){
|
839
|
-
case SCTP_COMM_LOST:
|
840
|
-
v_str = rb_str_new2("comm lost");
|
841
|
-
break;
|
842
|
-
case SCTP_COMM_UP:
|
843
|
-
v_str = rb_str_new2("comm up");
|
844
|
-
break;
|
845
|
-
case SCTP_RESTART:
|
846
|
-
v_str = rb_str_new2("restart");
|
847
|
-
break;
|
848
|
-
case SCTP_SHUTDOWN_COMP:
|
849
|
-
v_str = rb_str_new2("shutdown complete");
|
850
|
-
break;
|
851
|
-
case SCTP_CANT_STR_ASSOC:
|
852
|
-
v_str = rb_str_new2("association setup failed");
|
853
|
-
break;
|
854
|
-
default:
|
855
|
-
v_str = rb_str_new2("unknown");
|
856
|
-
}
|
857
|
-
|
858
|
-
v_notification = rb_struct_new(v_assoc_change_struct,
|
859
|
-
UINT2NUM(snp->sn_assoc_change.sac_type),
|
860
|
-
UINT2NUM(snp->sn_assoc_change.sac_length),
|
861
|
-
UINT2NUM(snp->sn_assoc_change.sac_state),
|
862
|
-
UINT2NUM(snp->sn_assoc_change.sac_error),
|
863
|
-
UINT2NUM(snp->sn_assoc_change.sac_outbound_streams),
|
864
|
-
UINT2NUM(snp->sn_assoc_change.sac_inbound_streams),
|
865
|
-
UINT2NUM(snp->sn_assoc_change.sac_assoc_id),
|
866
|
-
v_str
|
867
|
-
);
|
868
|
-
break;
|
869
|
-
case SCTP_PEER_ADDR_CHANGE:
|
870
|
-
switch(snp->sn_paddr_change.spc_state){
|
871
|
-
case SCTP_ADDR_AVAILABLE:
|
872
|
-
v_str = rb_str_new2("available");
|
873
|
-
break;
|
874
|
-
case SCTP_ADDR_UNREACHABLE:
|
875
|
-
v_str = rb_str_new2("unreachable");
|
876
|
-
break;
|
877
|
-
case SCTP_ADDR_REMOVED:
|
878
|
-
v_str = rb_str_new2("removed from association");
|
879
|
-
break;
|
880
|
-
case SCTP_ADDR_ADDED:
|
881
|
-
v_str = rb_str_new2("added to association");
|
882
|
-
break;
|
883
|
-
case SCTP_ADDR_MADE_PRIM:
|
884
|
-
v_str = rb_str_new2("primary destination");
|
885
|
-
break;
|
886
|
-
default:
|
887
|
-
v_str = rb_str_new2("unknown");
|
888
|
-
}
|
889
|
-
|
890
|
-
inet_ntop(
|
891
|
-
((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_family,
|
892
|
-
&(((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_addr),
|
893
|
-
str,
|
894
|
-
sizeof(str)
|
895
|
-
);
|
896
|
-
|
897
|
-
v_notification = rb_struct_new(v_peeraddr_change_struct,
|
898
|
-
UINT2NUM(snp->sn_paddr_change.spc_type),
|
899
|
-
UINT2NUM(snp->sn_paddr_change.spc_length),
|
900
|
-
rb_str_new2(str),
|
901
|
-
UINT2NUM(snp->sn_paddr_change.spc_state),
|
902
|
-
UINT2NUM(snp->sn_paddr_change.spc_error),
|
903
|
-
UINT2NUM(snp->sn_paddr_change.spc_assoc_id),
|
904
|
-
v_str
|
905
|
-
);
|
906
|
-
break;
|
907
|
-
case SCTP_REMOTE_ERROR:
|
908
|
-
v_temp = ALLOCA_N(VALUE, snp->sn_remote_error.sre_length);
|
909
|
-
|
910
|
-
for(i = 0; i < snp->sn_remote_error.sre_length; i++){
|
911
|
-
v_temp[i] = UINT2NUM(snp->sn_remote_error.sre_data[i]);
|
912
|
-
}
|
913
|
-
|
914
|
-
v_notification = rb_struct_new(v_remote_error_struct,
|
915
|
-
UINT2NUM(snp->sn_remote_error.sre_type),
|
916
|
-
UINT2NUM(snp->sn_remote_error.sre_length),
|
917
|
-
UINT2NUM(snp->sn_remote_error.sre_error),
|
918
|
-
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
919
|
-
rb_ary_new4(snp->sn_remote_error.sre_length, v_temp)
|
920
|
-
);
|
921
|
-
break;
|
922
|
-
#ifdef SCTP_SEND_FAILED_EVENT
|
923
|
-
case SCTP_SEND_FAILED_EVENT:
|
924
|
-
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed_event.ssf_length);
|
925
|
-
|
926
|
-
for(i = 0; i < snp->sn_send_failed_event.ssf_length; i++){
|
927
|
-
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssf_data[i]);
|
928
|
-
}
|
929
|
-
|
930
|
-
v_notification = rb_struct_new(v_send_failed_event_struct,
|
931
|
-
UINT2NUM(snp->sn_send_failed_event.ssf_type),
|
932
|
-
UINT2NUM(snp->sn_send_failed_event.ssf_length),
|
933
|
-
UINT2NUM(snp->sn_send_failed_event.ssf_error),
|
934
|
-
rb_struct_new(v_sndinfo_struct,
|
935
|
-
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
|
936
|
-
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
|
937
|
-
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
|
938
|
-
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
|
939
|
-
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
|
940
|
-
),
|
941
|
-
UINT2NUM(snp->sn_send_failed_event.ssf_assoc_id),
|
942
|
-
rb_ary_new4(snp->sn_send_failed_event.ssf_length, v_temp)
|
943
|
-
);
|
944
|
-
break;
|
945
|
-
#else
|
946
|
-
case SCTP_SEND_FAILED:
|
947
|
-
v_temp = ALLOCA_N(VALUE, snp->sn_send_failed.ssf_length);
|
948
|
-
|
949
|
-
for(i = 0; i < snp->sn_send_failed.ssf_length; i++){
|
950
|
-
v_temp[i] = UINT2NUM(snp->sn_send_failed.ssf_data[i]);
|
951
|
-
}
|
952
|
-
|
953
|
-
v_notification = rb_struct_new(v_send_failed_event_struct,
|
954
|
-
UINT2NUM(snp->sn_send_failed.ssf_type),
|
955
|
-
UINT2NUM(snp->sn_send_failed.ssf_length),
|
956
|
-
UINT2NUM(snp->sn_send_failed.ssf_error),
|
957
|
-
Qnil,
|
958
|
-
UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
|
959
|
-
rb_ary_new4(snp->sn_send_failed.ssf_length, v_temp)
|
960
|
-
);
|
961
|
-
break;
|
962
|
-
#endif
|
963
|
-
case SCTP_SHUTDOWN_EVENT:
|
964
|
-
v_notification = rb_struct_new(v_shutdown_event_struct,
|
965
|
-
UINT2NUM(snp->sn_shutdown_event.sse_type),
|
966
|
-
UINT2NUM(snp->sn_shutdown_event.sse_length),
|
967
|
-
UINT2NUM(snp->sn_shutdown_event.sse_assoc_id)
|
968
|
-
);
|
969
|
-
break;
|
970
|
-
case SCTP_ADAPTATION_INDICATION:
|
971
|
-
v_notification = rb_struct_new(v_adaptation_event_struct,
|
972
|
-
UINT2NUM(snp->sn_adaptation_event.sai_type),
|
973
|
-
UINT2NUM(snp->sn_adaptation_event.sai_length),
|
974
|
-
UINT2NUM(snp->sn_adaptation_event.sai_adaptation_ind),
|
975
|
-
UINT2NUM(snp->sn_adaptation_event.sai_assoc_id)
|
976
|
-
);
|
977
|
-
break;
|
978
|
-
case SCTP_PARTIAL_DELIVERY_EVENT:
|
979
|
-
v_notification = rb_struct_new(v_partial_delivery_event_struct,
|
980
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_type),
|
981
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_length),
|
982
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_indication),
|
983
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_stream),
|
984
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_seq),
|
985
|
-
UINT2NUM(snp->sn_pdapi_event.pdapi_assoc_id)
|
986
|
-
);
|
987
|
-
break;
|
988
|
-
case SCTP_AUTHENTICATION_EVENT:
|
989
|
-
v_notification = rb_struct_new(v_auth_event_struct,
|
990
|
-
UINT2NUM(snp->sn_authkey_event.auth_type),
|
991
|
-
UINT2NUM(snp->sn_authkey_event.auth_length),
|
992
|
-
UINT2NUM(snp->sn_authkey_event.auth_keynumber),
|
993
|
-
UINT2NUM(snp->sn_authkey_event.auth_indication),
|
994
|
-
UINT2NUM(snp->sn_authkey_event.auth_assoc_id)
|
995
|
-
);
|
996
|
-
break;
|
997
|
-
}
|
998
|
-
}
|
1051
|
+
if(flags & MSG_NOTIFICATION)
|
1052
|
+
v_notification = get_notification_info(buffer);
|
999
1053
|
|
1000
1054
|
if(NIL_P(v_notification))
|
1001
1055
|
v_message = rb_str_new(buffer, bytes);
|
@@ -1016,6 +1070,9 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
1016
1070
|
}
|
1017
1071
|
|
1018
1072
|
/*
|
1073
|
+
* call-seq:
|
1074
|
+
* SCTP::Socket#set_initmsg(options)
|
1075
|
+
*
|
1019
1076
|
* Set the initial parameters used by the socket when sending out the INIT message.
|
1020
1077
|
*
|
1021
1078
|
* Example:
|
@@ -1025,10 +1082,10 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
1025
1082
|
*
|
1026
1083
|
* The following parameters can be configured:
|
1027
1084
|
*
|
1028
|
-
*
|
1029
|
-
*
|
1030
|
-
*
|
1031
|
-
*
|
1085
|
+
* :output_streams - The number of outbound SCTP streams an application would like to request.
|
1086
|
+
* :input_streams - The maximum number of inbound streams an application is prepared to allow.
|
1087
|
+
* :max_attempts - How many times the the SCTP stack should send the initial INIT message before it's considered unreachable.
|
1088
|
+
* :timeout - The maximum RTO value for the INIT timer.
|
1032
1089
|
*
|
1033
1090
|
* By default these values are set to zero (i.e. ignored).
|
1034
1091
|
*/
|
@@ -1065,6 +1122,9 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
1065
1122
|
}
|
1066
1123
|
|
1067
1124
|
/*
|
1125
|
+
* call-seq:
|
1126
|
+
* SCTP::Socket#subscribe(options)
|
1127
|
+
*
|
1068
1128
|
* Subscribe to various notification type events, which will generate additional
|
1069
1129
|
* data that the socket may receive. The possible notification type events are
|
1070
1130
|
* as follows:
|
@@ -1089,11 +1149,8 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
1089
1149
|
* :adaptation
|
1090
1150
|
* :authentication
|
1091
1151
|
* :partial_delivery
|
1092
|
-
*
|
1093
|
-
* Not yet supported:
|
1094
|
-
*
|
1095
1152
|
* :sender_dry
|
1096
|
-
* :peer_error
|
1153
|
+
* :peer_error (aka remote error)
|
1097
1154
|
*
|
1098
1155
|
* Example:
|
1099
1156
|
*
|
@@ -1152,6 +1209,9 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
|
1152
1209
|
}
|
1153
1210
|
|
1154
1211
|
/*
|
1212
|
+
* call-seq:
|
1213
|
+
* SCTP::Socket#listen(backlog=128)
|
1214
|
+
*
|
1155
1215
|
* Marks the socket referred to by sockfd as a passive socket, i.e. a socket that
|
1156
1216
|
* will be used to accept incoming connection requests.
|
1157
1217
|
*
|
@@ -1195,6 +1255,9 @@ static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
|
|
1195
1255
|
}
|
1196
1256
|
|
1197
1257
|
/*
|
1258
|
+
* call-seq:
|
1259
|
+
* SCTP::Socket#peeloff(association_id)
|
1260
|
+
*
|
1198
1261
|
* Extracts an association contained by a one-to-many socket connection into
|
1199
1262
|
* a one-to-one style socket. Returns the socket descriptor (fileno).
|
1200
1263
|
*
|
@@ -1206,7 +1269,7 @@ static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
|
|
1206
1269
|
* while true
|
1207
1270
|
* info = socket.recvmsg
|
1208
1271
|
* assoc_fileno = socket.peeloff(info.association_id)
|
1209
|
-
* # ... Do something with this new
|
1272
|
+
* # ... Do something with this new fileno
|
1210
1273
|
* end
|
1211
1274
|
*/
|
1212
1275
|
static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
|
@@ -1224,6 +1287,24 @@ static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
|
|
1224
1287
|
return INT2NUM(assoc_fileno);
|
1225
1288
|
}
|
1226
1289
|
|
1290
|
+
/*
|
1291
|
+
* call-seq:
|
1292
|
+
* SCTP::Socket#get_default_send_params
|
1293
|
+
*
|
1294
|
+
* Returns the default set of parameters that a call to the sendto function
|
1295
|
+
* uses on this association. This is a struct that contains the following
|
1296
|
+
* members:
|
1297
|
+
*
|
1298
|
+
* * stream
|
1299
|
+
* * ssn
|
1300
|
+
* * flags
|
1301
|
+
* * ppid
|
1302
|
+
* * context
|
1303
|
+
* * ttl
|
1304
|
+
* * tsn
|
1305
|
+
* * cumtsn
|
1306
|
+
* * association_id
|
1307
|
+
*/
|
1227
1308
|
static VALUE rsctp_get_default_send_params(VALUE self){
|
1228
1309
|
int fileno;
|
1229
1310
|
socklen_t size;
|
@@ -1253,6 +1334,22 @@ static VALUE rsctp_get_default_send_params(VALUE self){
|
|
1253
1334
|
);
|
1254
1335
|
}
|
1255
1336
|
|
1337
|
+
/*
|
1338
|
+
* call-seq:
|
1339
|
+
* SCTP::Socket#get_association_info
|
1340
|
+
*
|
1341
|
+
* Returns the association specific parameters. This is a struct
|
1342
|
+
* that contains the following members:
|
1343
|
+
*
|
1344
|
+
* * association_id
|
1345
|
+
* * max_retransmission_count
|
1346
|
+
* * number_peer_destinations
|
1347
|
+
* * peer_receive_window
|
1348
|
+
* * local_receive_window
|
1349
|
+
* * cookie_life
|
1350
|
+
*
|
1351
|
+
* All values that refer to time values are measured in milliseconds.
|
1352
|
+
*/
|
1256
1353
|
static VALUE rsctp_get_association_info(VALUE self){
|
1257
1354
|
int fileno;
|
1258
1355
|
socklen_t size;
|
@@ -1279,6 +1376,21 @@ static VALUE rsctp_get_association_info(VALUE self){
|
|
1279
1376
|
);
|
1280
1377
|
}
|
1281
1378
|
|
1379
|
+
/*
|
1380
|
+
* call-seq:
|
1381
|
+
* SCTP::Socket#shutdown
|
1382
|
+
*
|
1383
|
+
* Shuts down socket send and receive operations.
|
1384
|
+
*
|
1385
|
+
* Optionally accepts an argument that specifieds the type of shutdown.
|
1386
|
+
* This can be one of the following values:
|
1387
|
+
*
|
1388
|
+
* * SHUT_RD - Disables further receive operations.
|
1389
|
+
* * SHUT_WR - Disables further send operations.
|
1390
|
+
* * SHUT_RDWR - Disables further send and receive operations.
|
1391
|
+
*
|
1392
|
+
* The default is SHUT_RDWR.
|
1393
|
+
*/
|
1282
1394
|
static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
1283
1395
|
int how, fileno;
|
1284
1396
|
VALUE v_how;
|
@@ -1301,6 +1413,19 @@ static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
|
1301
1413
|
return self;
|
1302
1414
|
}
|
1303
1415
|
|
1416
|
+
/*
|
1417
|
+
* call-seq:
|
1418
|
+
* SCTP::Socket#get_retransmission_info
|
1419
|
+
*
|
1420
|
+
* Returns the protocol parameters that are used to initialize and bind the
|
1421
|
+
* retransmission timeout (RTO) tunable. This is a struct with the following
|
1422
|
+
* members:
|
1423
|
+
*
|
1424
|
+
* * association_id
|
1425
|
+
* * initial
|
1426
|
+
* * max
|
1427
|
+
* * min
|
1428
|
+
*/
|
1304
1429
|
static VALUE rsctp_get_retransmission_info(VALUE self){
|
1305
1430
|
int fileno;
|
1306
1431
|
socklen_t size;
|
@@ -1326,6 +1451,9 @@ static VALUE rsctp_get_retransmission_info(VALUE self){
|
|
1326
1451
|
}
|
1327
1452
|
|
1328
1453
|
/*
|
1454
|
+
* call-seq:
|
1455
|
+
* SCTP::Socket#get_status
|
1456
|
+
*
|
1329
1457
|
* Get the status of a connected socket.
|
1330
1458
|
*
|
1331
1459
|
* Example:
|
@@ -1389,6 +1517,29 @@ static VALUE rsctp_get_status(VALUE self){
|
|
1389
1517
|
);
|
1390
1518
|
}
|
1391
1519
|
|
1520
|
+
/*
|
1521
|
+
* call-seq:
|
1522
|
+
* SCTP::Socket#get_subscriptions
|
1523
|
+
*
|
1524
|
+
* Returns a struct of events detailing which events have been
|
1525
|
+
* subscribed to by the socket. The struct contains the following
|
1526
|
+
* members:
|
1527
|
+
*
|
1528
|
+
* * data_io
|
1529
|
+
* * association
|
1530
|
+
* * address
|
1531
|
+
* * send_failure
|
1532
|
+
* * peer_error
|
1533
|
+
* * shutdown
|
1534
|
+
* * partial_delivery
|
1535
|
+
* * adaptation_layer
|
1536
|
+
* * authentication
|
1537
|
+
* * sender_dry
|
1538
|
+
* * stream_reset
|
1539
|
+
* * assoc_reset
|
1540
|
+
* * stream_change
|
1541
|
+
* * send_failure_event
|
1542
|
+
*/
|
1392
1543
|
static VALUE rsctp_get_subscriptions(VALUE self){
|
1393
1544
|
int fileno;
|
1394
1545
|
socklen_t size;
|
@@ -1422,6 +1573,492 @@ static VALUE rsctp_get_subscriptions(VALUE self){
|
|
1422
1573
|
);
|
1423
1574
|
}
|
1424
1575
|
|
1576
|
+
/*
|
1577
|
+
* call-seq:
|
1578
|
+
* SCTP::Socket#get_peer_address_params
|
1579
|
+
*
|
1580
|
+
* Applications can enable or disable heartbeats for any peer address of
|
1581
|
+
* an association, modify an address's heartbeat interval, force a
|
1582
|
+
* heartbeat to be sent immediately, and adjust the address's maximum
|
1583
|
+
* number of retransmissions sent before an address is considered
|
1584
|
+
* unreachable.
|
1585
|
+
*
|
1586
|
+
* This method returns a struct that contains this information. It contains
|
1587
|
+
* the following struct members.
|
1588
|
+
*
|
1589
|
+
* * association_id
|
1590
|
+
* * address
|
1591
|
+
* * heartbeat_interval
|
1592
|
+
* * max_retransmission_count
|
1593
|
+
* * path_mtu
|
1594
|
+
* * flags
|
1595
|
+
* * ipv6_flowlabel
|
1596
|
+
*/
|
1597
|
+
static VALUE rsctp_get_peer_address_params(VALUE self){
|
1598
|
+
int fileno;
|
1599
|
+
char str[16];
|
1600
|
+
socklen_t size;
|
1601
|
+
sctp_assoc_t assoc_id;
|
1602
|
+
struct sctp_paddrparams paddr;
|
1603
|
+
|
1604
|
+
bzero(&paddr, sizeof(paddr));
|
1605
|
+
bzero(&str, sizeof(str));
|
1606
|
+
|
1607
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1608
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1609
|
+
size = sizeof(struct sctp_paddrparams);
|
1610
|
+
|
1611
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_PEER_ADDR_PARAMS, (void*)&paddr, &size) < 0)
|
1612
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1613
|
+
|
1614
|
+
inet_ntop(AF_INET, ((struct sockaddr_in*)&paddr.spp_address), str, sizeof(str));
|
1615
|
+
|
1616
|
+
return rb_struct_new(
|
1617
|
+
v_sctp_peer_addr_params_struct,
|
1618
|
+
INT2NUM(paddr.spp_assoc_id),
|
1619
|
+
rb_str_new2(str),
|
1620
|
+
INT2NUM(paddr.spp_hbinterval),
|
1621
|
+
INT2NUM(paddr.spp_pathmaxrxt),
|
1622
|
+
INT2NUM(paddr.spp_pathmtu),
|
1623
|
+
INT2NUM(paddr.spp_flags),
|
1624
|
+
INT2NUM(paddr.spp_ipv6_flowlabel)
|
1625
|
+
);
|
1626
|
+
}
|
1627
|
+
|
1628
|
+
/*
|
1629
|
+
* call-seq:
|
1630
|
+
* SCTP::Socket#get_init_msg
|
1631
|
+
*
|
1632
|
+
* Returns a structure that contains various initialization parameters.
|
1633
|
+
*
|
1634
|
+
* * num_ostreams: A number representing the number of streams that the
|
1635
|
+
* application wishes to be able to send to.
|
1636
|
+
*
|
1637
|
+
* * max_instreams: The maximum number of inbound streams the application
|
1638
|
+
* is prepared to support.
|
1639
|
+
*
|
1640
|
+
* * max_attempts: The number of attempts the SCTP endpoint should make at
|
1641
|
+
* resending the INIT.
|
1642
|
+
*
|
1643
|
+
* * max_init_timeout: This value represents the largest Timeout or RTO value
|
1644
|
+
* (in milliseconds) to use in attempting an INIT.
|
1645
|
+
*/
|
1646
|
+
static VALUE rsctp_get_init_msg(VALUE self){
|
1647
|
+
int fileno;
|
1648
|
+
socklen_t size;
|
1649
|
+
sctp_assoc_t assoc_id;
|
1650
|
+
struct sctp_initmsg initmsg;
|
1651
|
+
|
1652
|
+
bzero(&initmsg, sizeof(initmsg));
|
1653
|
+
|
1654
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1655
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1656
|
+
size = sizeof(struct sctp_initmsg);
|
1657
|
+
|
1658
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_INITMSG, (void*)&initmsg, &size) < 0)
|
1659
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1660
|
+
|
1661
|
+
return rb_struct_new(
|
1662
|
+
v_sctp_initmsg_struct,
|
1663
|
+
INT2NUM(initmsg.sinit_num_ostreams),
|
1664
|
+
INT2NUM(initmsg.sinit_max_instreams),
|
1665
|
+
INT2NUM(initmsg.sinit_max_attempts),
|
1666
|
+
INT2NUM(initmsg.sinit_max_init_timeo)
|
1667
|
+
);
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
/*
|
1671
|
+
* call-seq:
|
1672
|
+
* SCTP::Socket#nodelay?
|
1673
|
+
*
|
1674
|
+
* Returns whether or not the nodelay option has been set.
|
1675
|
+
*/
|
1676
|
+
static VALUE rsctp_get_nodelay(VALUE self){
|
1677
|
+
int fileno;
|
1678
|
+
socklen_t size;
|
1679
|
+
sctp_assoc_t assoc_id;
|
1680
|
+
int value;
|
1681
|
+
|
1682
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1683
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1684
|
+
size = sizeof(int);
|
1685
|
+
|
1686
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_NODELAY, (void*)&value, &size) < 0)
|
1687
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1688
|
+
|
1689
|
+
if(value)
|
1690
|
+
return Qtrue;
|
1691
|
+
else
|
1692
|
+
return Qfalse;
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
/*
|
1696
|
+
* call-seq:
|
1697
|
+
* SCTP::Socket#nodelay=(bool)
|
1698
|
+
*
|
1699
|
+
* Turn on/off any Nagle-like algorithm. This means that packets are generally
|
1700
|
+
* sent as soon as possible and no unnecessary delays are introduced, at the
|
1701
|
+
* cost of more packets in the network.
|
1702
|
+
*/
|
1703
|
+
static VALUE rsctp_set_nodelay(VALUE self, VALUE v_bool){
|
1704
|
+
int fileno;
|
1705
|
+
socklen_t size;
|
1706
|
+
sctp_assoc_t assoc_id;
|
1707
|
+
int value;
|
1708
|
+
|
1709
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1710
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1711
|
+
size = sizeof(int);
|
1712
|
+
|
1713
|
+
if(NIL_P(v_bool) || v_bool == Qfalse)
|
1714
|
+
value = 0;
|
1715
|
+
else
|
1716
|
+
value = 1;
|
1717
|
+
|
1718
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_NODELAY, (void*)&value, &size) < 0)
|
1719
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1720
|
+
|
1721
|
+
if(value)
|
1722
|
+
return Qtrue;
|
1723
|
+
else
|
1724
|
+
return Qfalse;
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
/*
|
1728
|
+
* call-seq:
|
1729
|
+
* SCTP::Socket#autoclose
|
1730
|
+
*
|
1731
|
+
* Returns the number of seconds before socket associations automatically
|
1732
|
+
* shut down.
|
1733
|
+
*/
|
1734
|
+
static VALUE rsctp_get_autoclose(VALUE self){
|
1735
|
+
int fileno;
|
1736
|
+
socklen_t size;
|
1737
|
+
sctp_assoc_t assoc_id;
|
1738
|
+
int value;
|
1739
|
+
|
1740
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1741
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1742
|
+
size = sizeof(int);
|
1743
|
+
|
1744
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTOCLOSE, (void*)&value, &size) < 0)
|
1745
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1746
|
+
|
1747
|
+
return INT2NUM(value);
|
1748
|
+
}
|
1749
|
+
|
1750
|
+
/*
|
1751
|
+
* call-seq:
|
1752
|
+
* SCTP::Socket#autoclose=(seconds=0)
|
1753
|
+
*
|
1754
|
+
* When set it will cause associations that are idle for more than the specified
|
1755
|
+
* number of seconds to automatically close using the graceful shutdown
|
1756
|
+
* procedure. An association being idle is defined as an association that has
|
1757
|
+
* NOT sent or received user data.
|
1758
|
+
*
|
1759
|
+
* The special value of 0 indicates that no automatic close of any associations
|
1760
|
+
* should be performed, this is the default value. The option expects an integer
|
1761
|
+
* defining the number of seconds of idle time before an association is closed.
|
1762
|
+
*
|
1763
|
+
* An application using this option should enable receiving the association
|
1764
|
+
* change notification. This is the only mechanism an application is informed
|
1765
|
+
* about the closing of an association. After an association is closed, the
|
1766
|
+
* association ID assigned to it can be reused. An application should be aware
|
1767
|
+
* of this to avoid the possible problem of sending data to an incorrect peer
|
1768
|
+
* end point.
|
1769
|
+
*
|
1770
|
+
* This socket option is applicable to the one-to-many style socket only.
|
1771
|
+
*/
|
1772
|
+
static VALUE rsctp_set_autoclose(VALUE self, VALUE v_seconds){
|
1773
|
+
int fileno;
|
1774
|
+
socklen_t size;
|
1775
|
+
sctp_assoc_t assoc_id;
|
1776
|
+
int value;
|
1777
|
+
|
1778
|
+
value = NUM2INT(v_seconds);
|
1779
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1780
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1781
|
+
size = sizeof(int);
|
1782
|
+
|
1783
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTOCLOSE, (void*)&value, &size) < 0)
|
1784
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1785
|
+
|
1786
|
+
return v_seconds;
|
1787
|
+
}
|
1788
|
+
|
1789
|
+
/*
|
1790
|
+
* call-seq:
|
1791
|
+
* SCTP::Socket#enable_auth_support(association_id=nil)
|
1792
|
+
*
|
1793
|
+
* Enables auth for future associations.
|
1794
|
+
*/
|
1795
|
+
static VALUE rsctp_enable_auth_support(int argc, VALUE* argv, VALUE self){
|
1796
|
+
int fileno;
|
1797
|
+
socklen_t size;
|
1798
|
+
sctp_assoc_t assoc_id;
|
1799
|
+
struct sctp_assoc_value assoc_value;
|
1800
|
+
VALUE v_assoc_id;
|
1801
|
+
|
1802
|
+
rb_scan_args(argc, argv, "01", &v_assoc_id);
|
1803
|
+
|
1804
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1805
|
+
size = sizeof(struct sctp_assoc_value);
|
1806
|
+
|
1807
|
+
if(NIL_P(v_assoc_id))
|
1808
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1809
|
+
else
|
1810
|
+
assoc_id = NUM2INT(v_assoc_id);
|
1811
|
+
|
1812
|
+
assoc_value.assoc_id = assoc_id;
|
1813
|
+
assoc_value.assoc_value = 1;
|
1814
|
+
|
1815
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTH_SUPPORTED, (void*)&assoc_value, &size) < 0)
|
1816
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1817
|
+
|
1818
|
+
return self;
|
1819
|
+
}
|
1820
|
+
|
1821
|
+
/*
|
1822
|
+
* call-seq:
|
1823
|
+
* SCTP::Socket#set_shared_key(key, keynum, association_id=nil)
|
1824
|
+
*
|
1825
|
+
* This option will set a shared secret key which is used to build an
|
1826
|
+
* association shared key.
|
1827
|
+
*
|
1828
|
+
* The +key+ parameter should be a string (converted to an array of bytes
|
1829
|
+
* internally) that is to be used by the endpoint (or association) as the
|
1830
|
+
* shared secret key. If an empty string is used, then a null key is set.
|
1831
|
+
*
|
1832
|
+
* The +keynum+ parameter is the shared key identifier by which the
|
1833
|
+
* application will refer to this key. If a key of the specified index already
|
1834
|
+
* exists, then this new key will replace the old existing key. Note that
|
1835
|
+
* shared key identifier '0' defaults to a null key.
|
1836
|
+
*
|
1837
|
+
* The +association_id+, if non-zero, indicates what association that the shared
|
1838
|
+
* key is being set upon. If this argument is zero, then the shared key is set
|
1839
|
+
* upon the endpoint and all future associations will use this key (if not
|
1840
|
+
* changed by subsequent calls). By default this is the result of the
|
1841
|
+
* SCTP::Socket#association_id method.
|
1842
|
+
*
|
1843
|
+
* For one-to-one sockets, this parameter is ignored. Note, however, that this
|
1844
|
+
* option will set a key on the association if the socket is connected,
|
1845
|
+
* otherwise this will set a key on the endpoint.
|
1846
|
+
*/
|
1847
|
+
static VALUE rsctp_set_shared_key(int argc, VALUE* argv, VALUE self){
|
1848
|
+
int fileno, len;
|
1849
|
+
char* key;
|
1850
|
+
uint keynum;
|
1851
|
+
socklen_t size;
|
1852
|
+
sctp_assoc_t assoc_id;
|
1853
|
+
struct sctp_authkey* auth_key;
|
1854
|
+
VALUE v_key, v_keynumber, v_assoc_id;
|
1855
|
+
|
1856
|
+
rb_scan_args(argc, argv, "12", &v_key, &v_keynumber, &v_assoc_id);
|
1857
|
+
|
1858
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1859
|
+
key = StringValuePtr(v_key);
|
1860
|
+
len = strlen(key);
|
1861
|
+
unsigned char byte_array[len+1];
|
1862
|
+
|
1863
|
+
for(int i = 0; i < len; i++)
|
1864
|
+
byte_array[i] = key[i];
|
1865
|
+
|
1866
|
+
byte_array[len] = '\0';
|
1867
|
+
|
1868
|
+
auth_key = malloc(sizeof(auth_key) + sizeof(char[strlen(key)+1]));
|
1869
|
+
size = sizeof(auth_key);
|
1870
|
+
|
1871
|
+
if(NIL_P(v_assoc_id))
|
1872
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1873
|
+
else
|
1874
|
+
assoc_id = NUM2INT(v_assoc_id);
|
1875
|
+
|
1876
|
+
if(NIL_P(v_keynumber))
|
1877
|
+
keynum = 1;
|
1878
|
+
else
|
1879
|
+
keynum = NUM2INT(v_keynumber);
|
1880
|
+
|
1881
|
+
auth_key->sca_assoc_id = assoc_id;
|
1882
|
+
auth_key->sca_keynumber = keynum;
|
1883
|
+
auth_key->sca_keylength = strlen(key);
|
1884
|
+
memcpy(auth_key->sca_key, byte_array, sizeof(byte_array));
|
1885
|
+
|
1886
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTH_KEY, (void*)auth_key, &size) < 0)
|
1887
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1888
|
+
|
1889
|
+
return self;
|
1890
|
+
}
|
1891
|
+
|
1892
|
+
/*
|
1893
|
+
* call-seq:
|
1894
|
+
* SCTP::Socket#get_active_shared_key(keynum, association_id=nil)
|
1895
|
+
*
|
1896
|
+
* Gets the active shared key to be used to build the association shared key.
|
1897
|
+
*/
|
1898
|
+
static VALUE rsctp_get_active_shared_key(int argc, VALUE* argv, VALUE self){
|
1899
|
+
int fileno;
|
1900
|
+
socklen_t size;
|
1901
|
+
struct sctp_authkeyid authkey;
|
1902
|
+
sctp_assoc_t assoc_id;
|
1903
|
+
VALUE v_assoc_id, v_keynum;
|
1904
|
+
uint keynum;
|
1905
|
+
|
1906
|
+
rb_scan_args(argc, argv, "11", &v_keynum, &v_assoc_id);
|
1907
|
+
|
1908
|
+
bzero(&authkey, sizeof(authkey));
|
1909
|
+
|
1910
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1911
|
+
keynum = NUM2UINT(v_keynum);
|
1912
|
+
|
1913
|
+
if(NIL_P(v_assoc_id))
|
1914
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1915
|
+
else
|
1916
|
+
assoc_id = NUM2INT(v_assoc_id);
|
1917
|
+
|
1918
|
+
authkey.scact_assoc_id = assoc_id;
|
1919
|
+
authkey.scact_keynumber = keynum;
|
1920
|
+
|
1921
|
+
size = sizeof(struct sctp_authkeyid);
|
1922
|
+
|
1923
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTH_ACTIVE_KEY, (void*)&authkey, &size) < 0)
|
1924
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1925
|
+
|
1926
|
+
return INT2NUM(authkey.scact_keynumber);
|
1927
|
+
}
|
1928
|
+
|
1929
|
+
/*
|
1930
|
+
* call-seq:
|
1931
|
+
* SCTP::Socket#set_active_shared_key(keynum, association_id=nil)
|
1932
|
+
*
|
1933
|
+
* Sets the active shared key to be used to build the association shared key.
|
1934
|
+
*
|
1935
|
+
* Th +keynum+ parameter is the shared key identifier which the application is
|
1936
|
+
* requesting to become the active shared key to be used for sending
|
1937
|
+
* authenticated chunks. The key identifier MUST correspond to an existing
|
1938
|
+
* shared key. Note that shared key identifier '0' defaults to a null key.
|
1939
|
+
*
|
1940
|
+
* The association_idparameter, if non-zero, indicates what association that
|
1941
|
+
* the shared key identifier is being set active upon. If this element contains
|
1942
|
+
* zero, then the activation applies to the endpoint and all future
|
1943
|
+
* associations will use the specified shared key identifier.
|
1944
|
+
*
|
1945
|
+
* For one-to-one sockets, this parameter is ignored. Note, however, that this
|
1946
|
+
* option will set the active key on the association if the socket is connected,
|
1947
|
+
* otherwise this will set the default active key for the endpoint.
|
1948
|
+
*
|
1949
|
+
* By default, the association_id is the result of SCTP::Socket#association_id.
|
1950
|
+
*/
|
1951
|
+
static VALUE rsctp_set_active_shared_key(int argc, VALUE* argv, VALUE self){
|
1952
|
+
int fileno;
|
1953
|
+
socklen_t size;
|
1954
|
+
struct sctp_authkeyid authkey;
|
1955
|
+
sctp_assoc_t assoc_id;
|
1956
|
+
VALUE v_assoc_id, v_keynum;
|
1957
|
+
uint keynum;
|
1958
|
+
|
1959
|
+
rb_scan_args(argc, argv, "11", &v_keynum, &v_assoc_id);
|
1960
|
+
|
1961
|
+
keynum = NUM2UINT(v_keynum);
|
1962
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
1963
|
+
|
1964
|
+
if(NIL_P(v_assoc_id))
|
1965
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
1966
|
+
else
|
1967
|
+
assoc_id = NUM2INT(v_assoc_id);
|
1968
|
+
|
1969
|
+
authkey.scact_assoc_id = assoc_id;
|
1970
|
+
authkey.scact_keynumber = keynum;
|
1971
|
+
size = sizeof(struct sctp_authkeyid);
|
1972
|
+
|
1973
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTH_ACTIVE_KEY, (void*)&authkey, &size) < 0)
|
1974
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
1975
|
+
|
1976
|
+
return self;
|
1977
|
+
}
|
1978
|
+
|
1979
|
+
/*
|
1980
|
+
* call-seq:
|
1981
|
+
* SCTP::Socket#delete_shared_key(keynum, association_id=nil)
|
1982
|
+
*
|
1983
|
+
* Delete a shared secret key from use.
|
1984
|
+
*
|
1985
|
+
* The +keynum+ parameter is the shared key identifier which the application
|
1986
|
+
* is requesting to be deleted. The key identifier MUST correspond to an
|
1987
|
+
* existing shared key and MUST NOT be the current active key.
|
1988
|
+
*
|
1989
|
+
* If this parameter is zero, use of the null key identifier '0' is disabled
|
1990
|
+
* on the endpoint and/or association.
|
1991
|
+
*
|
1992
|
+
* The +association_id+ parameter, if non-zero, indicates what association that
|
1993
|
+
* the shared key identifier is being deleted from. By default this is the
|
1994
|
+
* association that's returned via SCTP::Socket#association_id.
|
1995
|
+
*
|
1996
|
+
* If set to zero, then the shared key is deleted from the endpoint and
|
1997
|
+
* and ALL associations will no longer use the specified shared key identifier
|
1998
|
+
* (unless otherwise set on the association using SCTP_AUTH_KEY).
|
1999
|
+
*
|
2000
|
+
* For one-to-one sockets, this parameter is ignored. Note, however, that this
|
2001
|
+
* option will delete the key from the association if the socket is connected,
|
2002
|
+
* otherwise this will delete the key from the endpoint.
|
2003
|
+
*/
|
2004
|
+
static VALUE rsctp_delete_shared_key(int argc, VALUE* argv, VALUE self){
|
2005
|
+
int fileno;
|
2006
|
+
socklen_t size;
|
2007
|
+
struct sctp_authkeyid authkey;
|
2008
|
+
sctp_assoc_t assoc_id;
|
2009
|
+
VALUE v_assoc_id, v_keynum;
|
2010
|
+
uint keynum;
|
2011
|
+
|
2012
|
+
rb_scan_args(argc, argv, "11", &v_keynum, &v_assoc_id);
|
2013
|
+
|
2014
|
+
bzero(&authkey, sizeof(authkey));
|
2015
|
+
|
2016
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
2017
|
+
keynum = NUM2UINT(v_keynum);
|
2018
|
+
|
2019
|
+
if(NIL_P(v_assoc_id))
|
2020
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
2021
|
+
else
|
2022
|
+
assoc_id = NUM2INT(v_assoc_id);
|
2023
|
+
|
2024
|
+
authkey.scact_assoc_id = assoc_id;
|
2025
|
+
authkey.scact_keynumber = keynum;
|
2026
|
+
|
2027
|
+
size = sizeof(struct sctp_authkeyid);
|
2028
|
+
|
2029
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_AUTH_DELETE_KEY, (void*)&authkey, &size) < 0)
|
2030
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
2031
|
+
|
2032
|
+
return INT2NUM(authkey.scact_keynumber);
|
2033
|
+
}
|
2034
|
+
|
2035
|
+
/*
|
2036
|
+
* call-seq:
|
2037
|
+
* SCTP::Socket#map_ipv4=(bool)
|
2038
|
+
*
|
2039
|
+
* If set to true and the socket is type PF_INET6, then IPv4 addresses will be
|
2040
|
+
* mapped to V6 representation. If set to false (the default), then no mapping
|
2041
|
+
* will be done of V4 addresses and a user will receive both PF_INET6 and
|
2042
|
+
* PF_INET type addresses on the socket.
|
2043
|
+
*/
|
2044
|
+
static VALUE rsctp_map_ipv4(VALUE self, VALUE v_bool){
|
2045
|
+
int fileno, boolean;
|
2046
|
+
sctp_assoc_t assoc_id;
|
2047
|
+
socklen_t size;
|
2048
|
+
|
2049
|
+
boolean = 0;
|
2050
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
2051
|
+
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
2052
|
+
|
2053
|
+
if(v_bool == Qtrue)
|
2054
|
+
boolean = 1;
|
2055
|
+
|
2056
|
+
if(sctp_opt_info(fileno, assoc_id, SCTP_I_WANT_MAPPED_V4_ADDR, (void*)&boolean, &size) < 0)
|
2057
|
+
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
2058
|
+
|
2059
|
+
return v_bool;
|
2060
|
+
}
|
2061
|
+
|
1425
2062
|
void Init_socket(void){
|
1426
2063
|
mSCTP = rb_define_module("SCTP");
|
1427
2064
|
cSocket = rb_define_class_under(mSCTP, "Socket", rb_cObject);
|
@@ -1442,7 +2079,7 @@ void Init_socket(void){
|
|
1442
2079
|
);
|
1443
2080
|
|
1444
2081
|
v_remote_error_struct = rb_struct_define(
|
1445
|
-
"RemoteError", "type", "length", "error", "association_id", "data", NULL
|
2082
|
+
"RemoteError", "type", "flags", "length", "error", "association_id", "data", NULL
|
1446
2083
|
);
|
1447
2084
|
|
1448
2085
|
v_send_failed_event_struct = rb_struct_define(
|
@@ -1470,6 +2107,10 @@ void Init_socket(void){
|
|
1470
2107
|
"AuthEvent", "type", "length", "key_number", "indication", "association_id", NULL
|
1471
2108
|
);
|
1472
2109
|
|
2110
|
+
v_sender_dry_event_struct = rb_struct_define(
|
2111
|
+
"SenderDryEvent", "type", "flags", "length", "association_id", NULL
|
2112
|
+
);
|
2113
|
+
|
1473
2114
|
v_sockaddr_in_struct = rb_struct_define(
|
1474
2115
|
"SockAddrIn", "family", "port", "address", NULL
|
1475
2116
|
);
|
@@ -1506,19 +2147,39 @@ void Init_socket(void){
|
|
1506
2147
|
"cumtsn", "context", "assocation_id", NULL
|
1507
2148
|
);
|
1508
2149
|
|
2150
|
+
v_sctp_peer_addr_params_struct = rb_struct_define(
|
2151
|
+
"PeerAddressParams", "association_id", "address", "heartbeat_interval",
|
2152
|
+
"max_retransmission_count", "path_mtu", "flags",
|
2153
|
+
"ipv6_flowlabel", NULL
|
2154
|
+
);
|
2155
|
+
|
2156
|
+
v_sctp_initmsg_struct = rb_struct_define(
|
2157
|
+
"InitMsg", "num_ostreams", "max_instreams", "max_attempts", "max_init_timeout", NULL
|
2158
|
+
);
|
2159
|
+
|
1509
2160
|
rb_define_method(cSocket, "initialize", rsctp_init, -1);
|
1510
2161
|
|
2162
|
+
rb_define_method(cSocket, "autoclose=", rsctp_set_autoclose, 1);
|
1511
2163
|
rb_define_method(cSocket, "bindx", rsctp_bindx, -1);
|
1512
2164
|
rb_define_method(cSocket, "close", rsctp_close, 0);
|
1513
2165
|
rb_define_method(cSocket, "connectx", rsctp_connectx, -1);
|
2166
|
+
rb_define_method(cSocket, "delete_shared_key", rsctp_delete_shared_key, -1);
|
2167
|
+
rb_define_method(cSocket, "enable_auth_support", rsctp_enable_auth_support, -1);
|
1514
2168
|
rb_define_method(cSocket, "getpeernames", rsctp_getpeernames, -1);
|
1515
2169
|
rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames, -1);
|
1516
|
-
rb_define_method(cSocket, "
|
2170
|
+
rb_define_method(cSocket, "get_active_shared_key", rsctp_get_active_shared_key, -1);
|
2171
|
+
rb_define_method(cSocket, "get_association_info", rsctp_get_association_info, 0);
|
2172
|
+
rb_define_method(cSocket, "get_autoclose", rsctp_get_autoclose, 0);
|
1517
2173
|
rb_define_method(cSocket, "get_default_send_params", rsctp_get_default_send_params, 0);
|
2174
|
+
rb_define_method(cSocket, "get_initmsg", rsctp_get_init_msg, 0);
|
2175
|
+
rb_define_method(cSocket, "get_peer_address_params", rsctp_get_peer_address_params, 0);
|
1518
2176
|
rb_define_method(cSocket, "get_retransmission_info", rsctp_get_retransmission_info, 0);
|
1519
|
-
rb_define_method(cSocket, "
|
2177
|
+
rb_define_method(cSocket, "get_status", rsctp_get_status, 0);
|
1520
2178
|
rb_define_method(cSocket, "get_subscriptions", rsctp_get_subscriptions, 0);
|
1521
2179
|
rb_define_method(cSocket, "listen", rsctp_listen, -1);
|
2180
|
+
rb_define_method(cSocket, "map_ipv4=", rsctp_map_ipv4, 1);
|
2181
|
+
rb_define_method(cSocket, "nodelay?", rsctp_get_nodelay, 0);
|
2182
|
+
rb_define_method(cSocket, "nodelay=", rsctp_set_nodelay, 1);
|
1522
2183
|
rb_define_method(cSocket, "peeloff", rsctp_peeloff, 1);
|
1523
2184
|
rb_define_method(cSocket, "recvmsg", rsctp_recvmsg, -1);
|
1524
2185
|
rb_define_method(cSocket, "send", rsctp_send, 1);
|
@@ -1532,7 +2193,10 @@ void Init_socket(void){
|
|
1532
2193
|
#endif
|
1533
2194
|
|
1534
2195
|
rb_define_method(cSocket, "sendmsg", rsctp_sendmsg, 1);
|
2196
|
+
rb_define_method(cSocket, "set_active_shared_key", rsctp_set_active_shared_key, -1);
|
1535
2197
|
rb_define_method(cSocket, "set_initmsg", rsctp_set_initmsg, 1);
|
2198
|
+
//rb_define_method(cSocket, "set_retransmission_info", rsctp_set_retransmission_info, -1);
|
2199
|
+
rb_define_method(cSocket, "set_shared_key", rsctp_set_shared_key, -1);
|
1536
2200
|
rb_define_method(cSocket, "shutdown", rsctp_shutdown, -1);
|
1537
2201
|
rb_define_method(cSocket, "subscribe", rsctp_subscribe, 1);
|
1538
2202
|
|
@@ -1542,8 +2206,8 @@ void Init_socket(void){
|
|
1542
2206
|
rb_define_attr(cSocket, "association_id", 1, 1);
|
1543
2207
|
rb_define_attr(cSocket, "port", 1, 1);
|
1544
2208
|
|
1545
|
-
/* 0.
|
1546
|
-
rb_define_const(cSocket, "VERSION", rb_str_new2("0.
|
2209
|
+
/* 0.1.1: The version of this library */
|
2210
|
+
rb_define_const(cSocket, "VERSION", rb_str_new2("0.1.1"));
|
1547
2211
|
|
1548
2212
|
/* send flags */
|
1549
2213
|
|