sctp-socket 0.0.7 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +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
|
|