sctp-socket 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +5 -0
- data/README.md +1 -1
- data/ext/sctp/socket.c +535 -206
- data/sctp-socket.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f9f0ecd09038bfc074d38f36b387c26a5f203c3d57ae5d6ad7f5b2c085e945f
|
|
4
|
+
data.tar.gz: 563a9e79224c46e71872de30a59a17ece441113dcab2cc8d4e153a7a89313b97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 714abd0b5f6ecb95778ddf81d03dbfc6d23f1bfcfdebe62d4bed25cf3aaecc869e1235f6e5c04a5de123b0022ed9b6bdcb39d13a340d0aae3f3e50340c10ad26
|
|
7
|
+
data.tar.gz: c88bcdc5f0f456e4ef3a75f9c06f52ba60600959bfe7d654d398dfe0a3c8f9a19d76ee4d577c119a0b367c525b6395172a86ff6e6259fff8e697b345e122f616
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.2.2 - 7-Jan-2026
|
|
2
|
+
* Added IPv6 support.
|
|
3
|
+
* Some internal refactoring and updates, potential memory leak fixes, etc.
|
|
4
|
+
* Some specs skipped unless root.
|
|
5
|
+
|
|
1
6
|
## 0.2.1 - 17-Aug-2025
|
|
2
7
|
* Several auth related methods were fixed.
|
|
3
8
|
* The recvv and recvmsg methods now allow for an optional buffer size argument.
|
data/README.md
CHANGED
data/ext/sctp/socket.c
CHANGED
|
@@ -63,6 +63,65 @@ VALUE v_sctp_initmsg_struct;
|
|
|
63
63
|
#define MAX_IP_ADDRESSES 8
|
|
64
64
|
#define DEFAULT_BUFFER_SIZE 1024
|
|
65
65
|
#define IP_BUFFER_SIZE INET6_ADDRSTRLEN
|
|
66
|
+
#define MAX_NOTIFICATION_DATA 8192
|
|
67
|
+
|
|
68
|
+
/*
|
|
69
|
+
* Helper function to parse an IP address string and fill a sockaddr_in or sockaddr_in6 structure.
|
|
70
|
+
* Supports both IPv4 and IPv6 addresses.
|
|
71
|
+
*
|
|
72
|
+
* @param addr_str The IP address string to parse
|
|
73
|
+
* @param port The port number (in host byte order)
|
|
74
|
+
* @param sin Pointer to sockaddr_in to fill (for IPv4)
|
|
75
|
+
* @param sin6 Pointer to sockaddr_in6 to fill (for IPv6)
|
|
76
|
+
* @param domain The address family (AF_INET or AF_INET6)
|
|
77
|
+
*/
|
|
78
|
+
static void parse_ip_address_v4(const char* addr_str, int port, struct sockaddr_in* sin){
|
|
79
|
+
bzero(sin, sizeof(*sin));
|
|
80
|
+
sin->sin_family = AF_INET;
|
|
81
|
+
sin->sin_port = htons(port);
|
|
82
|
+
if(inet_pton(AF_INET, addr_str, &sin->sin_addr) != 1)
|
|
83
|
+
rb_raise(rb_eArgError, "invalid IPv4 address: %s", addr_str);
|
|
84
|
+
#ifdef BSD
|
|
85
|
+
sin->sin_len = sizeof(struct sockaddr_in);
|
|
86
|
+
#endif
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static void parse_ip_address_v6(const char* addr_str, int port, struct sockaddr_in6* sin6){
|
|
90
|
+
bzero(sin6, sizeof(*sin6));
|
|
91
|
+
sin6->sin6_family = AF_INET6;
|
|
92
|
+
sin6->sin6_port = htons(port);
|
|
93
|
+
if(inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) != 1)
|
|
94
|
+
rb_raise(rb_eArgError, "invalid IPv6 address: %s", addr_str);
|
|
95
|
+
#ifdef BSD
|
|
96
|
+
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
|
97
|
+
#endif
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Helper function to set INADDR_ANY for IPv4.
|
|
102
|
+
*/
|
|
103
|
+
static void set_any_address_v4(int port, struct sockaddr_in* sin){
|
|
104
|
+
bzero(sin, sizeof(*sin));
|
|
105
|
+
sin->sin_family = AF_INET;
|
|
106
|
+
sin->sin_port = htons(port);
|
|
107
|
+
sin->sin_addr.s_addr = htonl(INADDR_ANY);
|
|
108
|
+
#ifdef BSD
|
|
109
|
+
sin->sin_len = sizeof(struct sockaddr_in);
|
|
110
|
+
#endif
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
* Helper function to set IN6ADDR_ANY for IPv6.
|
|
115
|
+
*/
|
|
116
|
+
static void set_any_address_v6(int port, struct sockaddr_in6* sin6){
|
|
117
|
+
bzero(sin6, sizeof(*sin6));
|
|
118
|
+
sin6->sin6_family = AF_INET6;
|
|
119
|
+
sin6->sin6_port = htons(port);
|
|
120
|
+
sin6->sin6_addr = in6addr_any;
|
|
121
|
+
#ifdef BSD
|
|
122
|
+
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
|
123
|
+
#endif
|
|
124
|
+
}
|
|
66
125
|
|
|
67
126
|
/*
|
|
68
127
|
* Convert a sockaddr_in structure to a Ruby struct.
|
|
@@ -197,12 +256,18 @@ VALUE get_notification_info(char* buffer){
|
|
|
197
256
|
v_str = rb_str_new2("unknown");
|
|
198
257
|
}
|
|
199
258
|
|
|
200
|
-
|
|
201
|
-
(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
259
|
+
{
|
|
260
|
+
struct sockaddr* sa = (struct sockaddr*)&snp->sn_paddr_change.spc_aaddr;
|
|
261
|
+
|
|
262
|
+
if(sa->sa_family == AF_INET6){
|
|
263
|
+
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
|
264
|
+
inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
|
|
265
|
+
}
|
|
266
|
+
else{
|
|
267
|
+
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
|
268
|
+
inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
206
271
|
|
|
207
272
|
v_notification = rb_struct_new(v_peeraddr_change_struct,
|
|
208
273
|
UINT2NUM(snp->sn_paddr_change.spc_type),
|
|
@@ -215,83 +280,150 @@ VALUE get_notification_info(char* buffer){
|
|
|
215
280
|
);
|
|
216
281
|
break;
|
|
217
282
|
case SCTP_REMOTE_ERROR:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
283
|
+
{
|
|
284
|
+
size_t data_len = 0;
|
|
285
|
+
VALUE v_data_ary;
|
|
286
|
+
|
|
287
|
+
// Calculate actual data length (total length minus fixed header)
|
|
288
|
+
if(snp->sn_remote_error.sre_length > offsetof(struct sctp_remote_error, sre_data))
|
|
289
|
+
data_len = snp->sn_remote_error.sre_length - offsetof(struct sctp_remote_error, sre_data);
|
|
290
|
+
|
|
291
|
+
// Bounds check to prevent stack overflow
|
|
292
|
+
if(data_len > MAX_NOTIFICATION_DATA)
|
|
293
|
+
data_len = MAX_NOTIFICATION_DATA;
|
|
294
|
+
|
|
295
|
+
if(data_len > 0){
|
|
296
|
+
v_temp = ALLOCA_N(VALUE, data_len);
|
|
297
|
+
for(i = 0; i < data_len; i++){
|
|
298
|
+
v_temp[i] = UINT2NUM(snp->sn_remote_error.sre_data[i]);
|
|
299
|
+
}
|
|
300
|
+
v_data_ary = rb_ary_new4(data_len, v_temp);
|
|
301
|
+
}
|
|
302
|
+
else{
|
|
303
|
+
v_data_ary = rb_ary_new();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
v_notification = rb_struct_new(v_remote_error_struct,
|
|
307
|
+
UINT2NUM(snp->sn_remote_error.sre_type),
|
|
308
|
+
UINT2NUM(snp->sn_remote_error.sre_flags),
|
|
309
|
+
UINT2NUM(snp->sn_remote_error.sre_length),
|
|
310
|
+
UINT2NUM(snp->sn_remote_error.sre_error),
|
|
311
|
+
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
|
312
|
+
v_data_ary
|
|
313
|
+
);
|
|
222
314
|
}
|
|
223
|
-
|
|
224
|
-
v_notification = rb_struct_new(v_remote_error_struct,
|
|
225
|
-
UINT2NUM(snp->sn_remote_error.sre_type),
|
|
226
|
-
UINT2NUM(snp->sn_remote_error.sre_flags),
|
|
227
|
-
UINT2NUM(snp->sn_remote_error.sre_length),
|
|
228
|
-
UINT2NUM(snp->sn_remote_error.sre_error),
|
|
229
|
-
UINT2NUM(snp->sn_remote_error.sre_assoc_id),
|
|
230
|
-
rb_ary_new4(snp->sn_remote_error.sre_length, v_temp)
|
|
231
|
-
);
|
|
232
315
|
break;
|
|
233
316
|
#ifdef SCTP_SEND_FAILED_EVENT
|
|
234
317
|
case SCTP_SEND_FAILED_EVENT:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
for(i = 0; i < snp->sn_send_failed_event.ssfe_length; i++){
|
|
239
|
-
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssfe_data[i]);
|
|
240
|
-
}
|
|
318
|
+
{
|
|
319
|
+
size_t data_len = 0;
|
|
320
|
+
VALUE v_data_ary;
|
|
241
321
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
322
|
+
#ifdef HAVE_STRUCT_SCTP_SEND_FAILED_EVENT_SSFE_LENGTH
|
|
323
|
+
// Calculate actual data length (total length minus fixed header)
|
|
324
|
+
if(snp->sn_send_failed_event.ssfe_length > offsetof(struct sctp_send_failed_event, ssfe_data))
|
|
325
|
+
data_len = snp->sn_send_failed_event.ssfe_length - offsetof(struct sctp_send_failed_event, ssfe_data);
|
|
326
|
+
|
|
327
|
+
// Bounds check to prevent stack overflow
|
|
328
|
+
if(data_len > MAX_NOTIFICATION_DATA)
|
|
329
|
+
data_len = MAX_NOTIFICATION_DATA;
|
|
330
|
+
|
|
331
|
+
if(data_len > 0){
|
|
332
|
+
v_temp = ALLOCA_N(VALUE, data_len);
|
|
333
|
+
for(i = 0; i < data_len; i++){
|
|
334
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssfe_data[i]);
|
|
335
|
+
}
|
|
336
|
+
v_data_ary = rb_ary_new4(data_len, v_temp);
|
|
337
|
+
}
|
|
338
|
+
else{
|
|
339
|
+
v_data_ary = rb_ary_new();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
|
343
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_type),
|
|
344
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_length),
|
|
345
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_error),
|
|
346
|
+
rb_struct_new(v_sndinfo_struct,
|
|
347
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
|
|
348
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
|
|
349
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
|
|
350
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
|
|
351
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
|
|
352
|
+
),
|
|
353
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_assoc_id),
|
|
354
|
+
v_data_ary
|
|
355
|
+
);
|
|
256
356
|
#else
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
357
|
+
// Calculate actual data length (total length minus fixed header)
|
|
358
|
+
if(snp->sn_send_failed_event.ssf_length > offsetof(struct sctp_send_failed_event, ssf_data))
|
|
359
|
+
data_len = snp->sn_send_failed_event.ssf_length - offsetof(struct sctp_send_failed_event, ssf_data);
|
|
360
|
+
|
|
361
|
+
// Bounds check to prevent stack overflow
|
|
362
|
+
if(data_len > MAX_NOTIFICATION_DATA)
|
|
363
|
+
data_len = MAX_NOTIFICATION_DATA;
|
|
364
|
+
|
|
365
|
+
if(data_len > 0){
|
|
366
|
+
v_temp = ALLOCA_N(VALUE, data_len);
|
|
367
|
+
for(i = 0; i < data_len; i++){
|
|
368
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssf_data[i]);
|
|
369
|
+
}
|
|
370
|
+
v_data_ary = rb_ary_new4(data_len, v_temp);
|
|
371
|
+
}
|
|
372
|
+
else{
|
|
373
|
+
v_data_ary = rb_ary_new();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
|
377
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_type),
|
|
378
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_length),
|
|
379
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_error),
|
|
380
|
+
rb_struct_new(v_sndinfo_struct,
|
|
381
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
|
|
382
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
|
|
383
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
|
|
384
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
|
|
385
|
+
UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
|
|
386
|
+
),
|
|
387
|
+
UINT2NUM(snp->sn_send_failed_event.ssf_assoc_id),
|
|
388
|
+
v_data_ary
|
|
389
|
+
);
|
|
277
390
|
#endif
|
|
391
|
+
}
|
|
278
392
|
break;
|
|
279
393
|
#else
|
|
280
394
|
case SCTP_SEND_FAILED:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
395
|
+
{
|
|
396
|
+
size_t data_len = 0;
|
|
397
|
+
VALUE v_data_ary;
|
|
398
|
+
|
|
399
|
+
// Calculate actual data length (total length minus fixed header)
|
|
400
|
+
if(snp->sn_send_failed.ssf_length > offsetof(struct sctp_send_failed, ssf_data))
|
|
401
|
+
data_len = snp->sn_send_failed.ssf_length - offsetof(struct sctp_send_failed, ssf_data);
|
|
402
|
+
|
|
403
|
+
// Bounds check to prevent stack overflow
|
|
404
|
+
if(data_len > MAX_NOTIFICATION_DATA)
|
|
405
|
+
data_len = MAX_NOTIFICATION_DATA;
|
|
406
|
+
|
|
407
|
+
if(data_len > 0){
|
|
408
|
+
v_temp = ALLOCA_N(VALUE, data_len);
|
|
409
|
+
for(i = 0; i < data_len; i++){
|
|
410
|
+
v_temp[i] = UINT2NUM(snp->sn_send_failed.ssf_data[i]);
|
|
411
|
+
}
|
|
412
|
+
v_data_ary = rb_ary_new4(data_len, v_temp);
|
|
413
|
+
}
|
|
414
|
+
else{
|
|
415
|
+
v_data_ary = rb_ary_new();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
v_notification = rb_struct_new(v_send_failed_event_struct,
|
|
419
|
+
UINT2NUM(snp->sn_send_failed.ssf_type),
|
|
420
|
+
UINT2NUM(snp->sn_send_failed.ssf_length),
|
|
421
|
+
UINT2NUM(snp->sn_send_failed.ssf_error),
|
|
422
|
+
Qnil,
|
|
423
|
+
UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
|
|
424
|
+
v_data_ary
|
|
425
|
+
);
|
|
285
426
|
}
|
|
286
|
-
|
|
287
|
-
v_notification = rb_struct_new(v_send_failed_event_struct,
|
|
288
|
-
UINT2NUM(snp->sn_send_failed.ssf_type),
|
|
289
|
-
UINT2NUM(snp->sn_send_failed.ssf_length),
|
|
290
|
-
UINT2NUM(snp->sn_send_failed.ssf_error),
|
|
291
|
-
Qnil,
|
|
292
|
-
UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
|
|
293
|
-
rb_ary_new4(snp->sn_send_failed.ssf_length, v_temp)
|
|
294
|
-
);
|
|
295
427
|
break;
|
|
296
428
|
#endif
|
|
297
429
|
case SCTP_SHUTDOWN_EVENT:
|
|
@@ -451,14 +583,11 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
|
|
|
451
583
|
* Returns the port that it was bound to.
|
|
452
584
|
*/
|
|
453
585
|
static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
454
|
-
struct sockaddr_in addrs[MAX_IP_ADDRESSES];
|
|
455
586
|
int i, fileno, num_ip, flags, domain, port, on;
|
|
456
587
|
VALUE v_addresses, v_port, v_flags, v_address, v_reuse_addr, v_options;
|
|
457
588
|
|
|
458
589
|
rb_scan_args(argc, argv, "01", &v_options);
|
|
459
590
|
|
|
460
|
-
bzero(&addrs, sizeof(addrs));
|
|
461
|
-
|
|
462
591
|
if(NIL_P(v_options))
|
|
463
592
|
v_options = rb_hash_new();
|
|
464
593
|
|
|
@@ -485,37 +614,51 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
|
485
614
|
if(num_ip > MAX_IP_ADDRESSES)
|
|
486
615
|
rb_raise(rb_eArgError, "too many IP addresses to bind, maximum is eight");
|
|
487
616
|
|
|
617
|
+
CHECK_SOCKET_CLOSED(self);
|
|
618
|
+
|
|
488
619
|
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
|
489
620
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
490
621
|
|
|
491
|
-
if(!NIL_P(v_addresses)){
|
|
492
|
-
for(i = 0; i < num_ip; i++){
|
|
493
|
-
v_address = RARRAY_PTR(v_addresses)[i];
|
|
494
|
-
addrs[i].sin_family = domain;
|
|
495
|
-
addrs[i].sin_port = htons(port);
|
|
496
|
-
addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
|
|
497
|
-
#ifdef BSD
|
|
498
|
-
addrs[i].sin_len = sizeof(struct sockaddr_in);
|
|
499
|
-
#endif
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
else{
|
|
503
|
-
addrs[0].sin_family = domain;
|
|
504
|
-
addrs[0].sin_port = htons(port);
|
|
505
|
-
addrs[0].sin_addr.s_addr = htonl(INADDR_ANY);
|
|
506
|
-
#ifdef BSD
|
|
507
|
-
addrs[0].sin_len = sizeof(struct sockaddr_in);
|
|
508
|
-
#endif
|
|
509
|
-
}
|
|
510
|
-
|
|
511
622
|
if(v_reuse_addr == Qtrue){
|
|
512
623
|
on = 1;
|
|
513
624
|
if(setsockopt(fileno, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
|
514
625
|
rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
|
|
515
626
|
}
|
|
516
627
|
|
|
517
|
-
if(
|
|
518
|
-
|
|
628
|
+
if(domain == AF_INET6){
|
|
629
|
+
struct sockaddr_in6 addrs6[MAX_IP_ADDRESSES];
|
|
630
|
+
bzero(&addrs6, sizeof(addrs6));
|
|
631
|
+
|
|
632
|
+
if(!NIL_P(v_addresses)){
|
|
633
|
+
for(i = 0; i < num_ip; i++){
|
|
634
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
635
|
+
parse_ip_address_v6(StringValueCStr(v_address), port, &addrs6[i]);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
else{
|
|
639
|
+
set_any_address_v6(port, &addrs6[0]);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
if(sctp_bindx(fileno, (struct sockaddr *)addrs6, num_ip, flags) != 0)
|
|
643
|
+
rb_raise(rb_eSystemCallError, "sctp_bindx: %s", strerror(errno));
|
|
644
|
+
}
|
|
645
|
+
else{
|
|
646
|
+
struct sockaddr_in addrs[MAX_IP_ADDRESSES];
|
|
647
|
+
bzero(&addrs, sizeof(addrs));
|
|
648
|
+
|
|
649
|
+
if(!NIL_P(v_addresses)){
|
|
650
|
+
for(i = 0; i < num_ip; i++){
|
|
651
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
652
|
+
parse_ip_address_v4(StringValueCStr(v_address), port, &addrs[i]);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else{
|
|
656
|
+
set_any_address_v4(port, &addrs[0]);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if(sctp_bindx(fileno, (struct sockaddr *)addrs, num_ip, flags) != 0)
|
|
660
|
+
rb_raise(rb_eSystemCallError, "sctp_bindx: %s", strerror(errno));
|
|
661
|
+
}
|
|
519
662
|
|
|
520
663
|
if(port == 0){
|
|
521
664
|
struct sockaddr_in sin;
|
|
@@ -550,10 +693,9 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
|
|
|
550
693
|
* methods will automatically establish associations.
|
|
551
694
|
*/
|
|
552
695
|
static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
|
|
553
|
-
|
|
554
|
-
int i, num_ip, fileno;
|
|
696
|
+
int i, num_ip, fileno, domain, port;
|
|
555
697
|
sctp_assoc_t assoc;
|
|
556
|
-
VALUE v_address,
|
|
698
|
+
VALUE v_address, v_options, v_addresses, v_port;
|
|
557
699
|
|
|
558
700
|
rb_scan_args(argc, argv, "01", &v_options);
|
|
559
701
|
|
|
@@ -571,25 +713,41 @@ static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
|
|
|
571
713
|
if(NIL_P(v_port))
|
|
572
714
|
rb_raise(rb_eArgError, "you must specify a port");
|
|
573
715
|
|
|
574
|
-
|
|
716
|
+
CHECK_SOCKET_CLOSED(self);
|
|
717
|
+
|
|
718
|
+
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
|
719
|
+
port = NUM2INT(v_port);
|
|
720
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
575
721
|
|
|
576
722
|
num_ip = (int)RARRAY_LEN(v_addresses);
|
|
577
|
-
bzero(&addrs, sizeof(addrs));
|
|
578
723
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
724
|
+
if(num_ip > MAX_IP_ADDRESSES)
|
|
725
|
+
rb_raise(rb_eArgError, "too many IP addresses, maximum is eight");
|
|
726
|
+
|
|
727
|
+
if(domain == AF_INET6){
|
|
728
|
+
struct sockaddr_in6 addrs6[MAX_IP_ADDRESSES];
|
|
729
|
+
bzero(&addrs6, sizeof(addrs6));
|
|
730
|
+
|
|
731
|
+
for(i = 0; i < num_ip; i++){
|
|
732
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
733
|
+
parse_ip_address_v6(StringValueCStr(v_address), port, &addrs6[i]);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
if(sctp_connectx(fileno, (struct sockaddr *)addrs6, num_ip, &assoc) < 0)
|
|
737
|
+
rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
|
|
587
738
|
}
|
|
739
|
+
else{
|
|
740
|
+
struct sockaddr_in addrs[MAX_IP_ADDRESSES];
|
|
741
|
+
bzero(&addrs, sizeof(addrs));
|
|
588
742
|
|
|
589
|
-
|
|
743
|
+
for(i = 0; i < num_ip; i++){
|
|
744
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
745
|
+
parse_ip_address_v4(StringValueCStr(v_address), port, &addrs[i]);
|
|
746
|
+
}
|
|
590
747
|
|
|
591
|
-
|
|
592
|
-
|
|
748
|
+
if(sctp_connectx(fileno, (struct sockaddr *)addrs, num_ip, &assoc) < 0)
|
|
749
|
+
rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
|
|
750
|
+
}
|
|
593
751
|
|
|
594
752
|
rb_iv_set(self, "@association_id", INT2NUM(assoc));
|
|
595
753
|
|
|
@@ -731,8 +889,18 @@ static VALUE rsctp_getpeernames(int argc, VALUE* argv, VALUE self){
|
|
|
731
889
|
}
|
|
732
890
|
|
|
733
891
|
for(i = 0; i < num_addrs; i++){
|
|
892
|
+
struct sockaddr* sa = &addrs[i];
|
|
734
893
|
bzero(&str, sizeof(str));
|
|
735
|
-
|
|
894
|
+
|
|
895
|
+
if(sa->sa_family == AF_INET6){
|
|
896
|
+
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
|
897
|
+
inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
|
|
898
|
+
}
|
|
899
|
+
else{
|
|
900
|
+
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
|
901
|
+
inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
|
902
|
+
}
|
|
903
|
+
|
|
736
904
|
rb_ary_push(v_array, rb_str_new2(str));
|
|
737
905
|
}
|
|
738
906
|
|
|
@@ -792,8 +960,18 @@ static VALUE rsctp_getlocalnames(int argc, VALUE* argv, VALUE self){
|
|
|
792
960
|
}
|
|
793
961
|
|
|
794
962
|
for(i = 0; i < num_addrs; i++){
|
|
963
|
+
struct sockaddr* sa = &addrs[i];
|
|
795
964
|
bzero(&str, sizeof(str));
|
|
796
|
-
|
|
965
|
+
|
|
966
|
+
if(sa->sa_family == AF_INET6){
|
|
967
|
+
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
|
968
|
+
inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
|
|
969
|
+
}
|
|
970
|
+
else{
|
|
971
|
+
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
|
972
|
+
inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
|
973
|
+
}
|
|
974
|
+
|
|
797
975
|
rb_ary_push(v_array, rb_str_new2(str));
|
|
798
976
|
}
|
|
799
977
|
|
|
@@ -832,9 +1010,8 @@ static VALUE rsctp_getlocalnames(int argc, VALUE* argv, VALUE self){
|
|
|
832
1010
|
static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
833
1011
|
VALUE v_msg, v_message, v_addresses;
|
|
834
1012
|
struct iovec iov[IOV_MAX];
|
|
835
|
-
struct sockaddr_in* addrs;
|
|
836
1013
|
struct sctp_sendv_spa spa;
|
|
837
|
-
int i, fileno, size, num_ip;
|
|
1014
|
+
int i, fileno, size, num_ip, domain, port;
|
|
838
1015
|
ssize_t num_bytes;
|
|
839
1016
|
|
|
840
1017
|
Check_Type(v_options, T_HASH);
|
|
@@ -856,10 +1033,11 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
|
856
1033
|
if(!NIL_P(v_addresses)){
|
|
857
1034
|
Check_Type(v_addresses, T_ARRAY);
|
|
858
1035
|
num_ip = (int)RARRAY_LEN(v_addresses);
|
|
859
|
-
|
|
1036
|
+
|
|
1037
|
+
if(num_ip > MAX_IP_ADDRESSES)
|
|
1038
|
+
rb_raise(rb_eArgError, "too many IP addresses, maximum is eight");
|
|
860
1039
|
}
|
|
861
1040
|
else{
|
|
862
|
-
addrs = NULL;
|
|
863
1041
|
num_ip = 0;
|
|
864
1042
|
}
|
|
865
1043
|
|
|
@@ -877,8 +1055,15 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
|
877
1055
|
spa.sendv_sndinfo.snd_flags = SCTP_UNORDERED;
|
|
878
1056
|
spa.sendv_sndinfo.snd_assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
879
1057
|
|
|
880
|
-
|
|
881
|
-
|
|
1058
|
+
for(i = 0; i < size; i++){
|
|
1059
|
+
v_msg = RARRAY_AREF(v_message, i);
|
|
1060
|
+
iov[i].iov_base = StringValueCStr(v_msg);
|
|
1061
|
+
iov[i].iov_len = RSTRING_LEN(v_msg);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
|
1065
|
+
|
|
1066
|
+
if(num_ip > 0){
|
|
882
1067
|
VALUE v_address, v_port;
|
|
883
1068
|
|
|
884
1069
|
v_port = rb_iv_get(self, "@port");
|
|
@@ -888,36 +1073,62 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
|
|
|
888
1073
|
else
|
|
889
1074
|
port = NUM2INT(v_port);
|
|
890
1075
|
|
|
891
|
-
domain
|
|
1076
|
+
if(domain == AF_INET6){
|
|
1077
|
+
struct sockaddr_in6* addrs6 = (struct sockaddr_in6*)alloca(num_ip * sizeof(struct sockaddr_in6));
|
|
1078
|
+
bzero(addrs6, num_ip * sizeof(struct sockaddr_in6));
|
|
892
1079
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
1080
|
+
for(i = 0; i < num_ip; i++){
|
|
1081
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
1082
|
+
parse_ip_address_v6(StringValueCStr(v_address), port, &addrs6[i]);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
num_bytes = (ssize_t)sctp_sendv(
|
|
1086
|
+
fileno,
|
|
1087
|
+
iov,
|
|
1088
|
+
size,
|
|
1089
|
+
(struct sockaddr*)addrs6,
|
|
1090
|
+
num_ip,
|
|
1091
|
+
&spa,
|
|
1092
|
+
sizeof(spa),
|
|
1093
|
+
SCTP_SENDV_SPA,
|
|
1094
|
+
0
|
|
1095
|
+
);
|
|
901
1096
|
}
|
|
902
|
-
|
|
1097
|
+
else{
|
|
1098
|
+
struct sockaddr_in* addrs = (struct sockaddr_in*)alloca(num_ip * sizeof(struct sockaddr_in));
|
|
1099
|
+
bzero(addrs, num_ip * sizeof(struct sockaddr_in));
|
|
903
1100
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
1101
|
+
for(i = 0; i < num_ip; i++){
|
|
1102
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
1103
|
+
parse_ip_address_v4(StringValueCStr(v_address), port, &addrs[i]);
|
|
1104
|
+
}
|
|
909
1105
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1106
|
+
num_bytes = (ssize_t)sctp_sendv(
|
|
1107
|
+
fileno,
|
|
1108
|
+
iov,
|
|
1109
|
+
size,
|
|
1110
|
+
(struct sockaddr*)addrs,
|
|
1111
|
+
num_ip,
|
|
1112
|
+
&spa,
|
|
1113
|
+
sizeof(spa),
|
|
1114
|
+
SCTP_SENDV_SPA,
|
|
1115
|
+
0
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
else{
|
|
1120
|
+
num_bytes = (ssize_t)sctp_sendv(
|
|
1121
|
+
fileno,
|
|
1122
|
+
iov,
|
|
1123
|
+
size,
|
|
1124
|
+
NULL,
|
|
1125
|
+
0,
|
|
1126
|
+
&spa,
|
|
1127
|
+
sizeof(spa),
|
|
1128
|
+
SCTP_SENDV_SPA,
|
|
1129
|
+
0
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
921
1132
|
|
|
922
1133
|
if(num_bytes < 0)
|
|
923
1134
|
rb_raise(rb_eSystemCallError, "sctp_sendv: %s", strerror(errno));
|
|
@@ -970,6 +1181,8 @@ static VALUE rsctp_recvv(int argc, VALUE* argv, VALUE self){
|
|
|
970
1181
|
|
|
971
1182
|
rb_scan_args(argc, argv, "02", &v_flags, &v_buffer_size);
|
|
972
1183
|
|
|
1184
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1185
|
+
|
|
973
1186
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
974
1187
|
|
|
975
1188
|
if(NIL_P(v_flags))
|
|
@@ -1116,6 +1329,8 @@ static VALUE rsctp_send(VALUE self, VALUE v_options){
|
|
|
1116
1329
|
else
|
|
1117
1330
|
assoc_id = NUM2INT(v_assoc_id);
|
|
1118
1331
|
|
|
1332
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1333
|
+
|
|
1119
1334
|
info.sinfo_stream = stream;
|
|
1120
1335
|
info.sinfo_flags = send_flags;
|
|
1121
1336
|
info.sinfo_ppid = ppid;
|
|
@@ -1176,13 +1391,10 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
|
1176
1391
|
uint16_t stream;
|
|
1177
1392
|
uint32_t ppid, flags, ttl, context;
|
|
1178
1393
|
ssize_t num_bytes;
|
|
1179
|
-
|
|
1180
|
-
int fileno, size, num_ip;
|
|
1394
|
+
int fileno, num_ip, domain;
|
|
1181
1395
|
|
|
1182
1396
|
Check_Type(v_options, T_HASH);
|
|
1183
1397
|
|
|
1184
|
-
bzero(&addrs, sizeof(addrs));
|
|
1185
|
-
|
|
1186
1398
|
v_msg = rb_hash_aref2(v_options, "message");
|
|
1187
1399
|
v_stream = rb_hash_aref2(v_options, "stream");
|
|
1188
1400
|
v_ppid = rb_hash_aref2(v_options, "ppid");
|
|
@@ -1222,12 +1434,21 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
|
1222
1434
|
else
|
|
1223
1435
|
context = NUM2INT(v_context);
|
|
1224
1436
|
|
|
1437
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1438
|
+
|
|
1439
|
+
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1440
|
+
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
|
1441
|
+
|
|
1225
1442
|
if(!NIL_P(v_addresses)){
|
|
1226
1443
|
int i, port;
|
|
1227
1444
|
VALUE v_address, v_port;
|
|
1228
1445
|
|
|
1229
1446
|
Check_Type(v_addresses, T_ARRAY);
|
|
1230
1447
|
num_ip = (int)RARRAY_LEN(v_addresses);
|
|
1448
|
+
|
|
1449
|
+
if(num_ip > MAX_IP_ADDRESSES)
|
|
1450
|
+
rb_raise(rb_eArgError, "too many IP addresses, maximum is eight");
|
|
1451
|
+
|
|
1231
1452
|
v_port = rb_hash_aref2(v_options, "port");
|
|
1232
1453
|
|
|
1233
1454
|
if(NIL_P(v_port))
|
|
@@ -1235,47 +1456,92 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
|
1235
1456
|
else
|
|
1236
1457
|
port = NUM2INT(v_port);
|
|
1237
1458
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1459
|
+
if(domain == AF_INET6){
|
|
1460
|
+
struct sockaddr_in6 addrs6[MAX_IP_ADDRESSES];
|
|
1461
|
+
|
|
1462
|
+
bzero(&addrs6, sizeof(addrs6));
|
|
1463
|
+
|
|
1464
|
+
for(i = 0; i < num_ip; i++){
|
|
1465
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
1466
|
+
parse_ip_address_v6(StringValueCStr(v_address), port, &addrs6[i]);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1243
1469
|
#ifdef BSD
|
|
1244
|
-
|
|
1470
|
+
num_bytes = (ssize_t)sctp_sendmsgx(
|
|
1471
|
+
fileno,
|
|
1472
|
+
StringValueCStr(v_msg),
|
|
1473
|
+
RSTRING_LEN(v_msg),
|
|
1474
|
+
(struct sockaddr*)addrs6,
|
|
1475
|
+
num_ip,
|
|
1476
|
+
ppid,
|
|
1477
|
+
flags,
|
|
1478
|
+
stream,
|
|
1479
|
+
ttl,
|
|
1480
|
+
context
|
|
1481
|
+
);
|
|
1482
|
+
#else
|
|
1483
|
+
num_bytes = (ssize_t)sctp_sendmsg(
|
|
1484
|
+
fileno,
|
|
1485
|
+
StringValueCStr(v_msg),
|
|
1486
|
+
RSTRING_LEN(v_msg),
|
|
1487
|
+
(struct sockaddr*)addrs6,
|
|
1488
|
+
num_ip * sizeof(struct sockaddr_in6),
|
|
1489
|
+
ppid,
|
|
1490
|
+
flags,
|
|
1491
|
+
stream,
|
|
1492
|
+
ttl,
|
|
1493
|
+
context
|
|
1494
|
+
);
|
|
1245
1495
|
#endif
|
|
1246
1496
|
}
|
|
1497
|
+
else{
|
|
1498
|
+
struct sockaddr_in addrs[MAX_IP_ADDRESSES];
|
|
1247
1499
|
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1250
|
-
else{
|
|
1251
|
-
num_ip = 0;
|
|
1252
|
-
size = 0;
|
|
1253
|
-
}
|
|
1500
|
+
bzero(&addrs, sizeof(addrs));
|
|
1254
1501
|
|
|
1255
|
-
|
|
1502
|
+
for(i = 0; i < num_ip; i++){
|
|
1503
|
+
v_address = RARRAY_AREF(v_addresses, i);
|
|
1504
|
+
parse_ip_address_v4(StringValueCStr(v_address), port, &addrs[i]);
|
|
1505
|
+
}
|
|
1256
1506
|
|
|
1257
1507
|
#ifdef BSD
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1508
|
+
num_bytes = (ssize_t)sctp_sendmsgx(
|
|
1509
|
+
fileno,
|
|
1510
|
+
StringValueCStr(v_msg),
|
|
1511
|
+
RSTRING_LEN(v_msg),
|
|
1512
|
+
(struct sockaddr*)addrs,
|
|
1513
|
+
num_ip,
|
|
1514
|
+
ppid,
|
|
1515
|
+
flags,
|
|
1516
|
+
stream,
|
|
1517
|
+
ttl,
|
|
1518
|
+
context
|
|
1519
|
+
);
|
|
1520
|
+
#else
|
|
1521
|
+
num_bytes = (ssize_t)sctp_sendmsg(
|
|
1522
|
+
fileno,
|
|
1523
|
+
StringValueCStr(v_msg),
|
|
1524
|
+
RSTRING_LEN(v_msg),
|
|
1525
|
+
(struct sockaddr*)addrs,
|
|
1526
|
+
num_ip * sizeof(struct sockaddr_in),
|
|
1527
|
+
ppid,
|
|
1528
|
+
flags,
|
|
1529
|
+
stream,
|
|
1530
|
+
ttl,
|
|
1531
|
+
context
|
|
1532
|
+
);
|
|
1533
|
+
#endif
|
|
1534
|
+
}
|
|
1271
1535
|
}
|
|
1272
1536
|
else{
|
|
1537
|
+
// No addresses - use empty addrs
|
|
1538
|
+
num_ip = 0;
|
|
1273
1539
|
num_bytes = (ssize_t)sctp_sendmsg(
|
|
1274
1540
|
fileno,
|
|
1275
1541
|
StringValueCStr(v_msg),
|
|
1276
1542
|
RSTRING_LEN(v_msg),
|
|
1277
|
-
|
|
1278
|
-
|
|
1543
|
+
NULL,
|
|
1544
|
+
0,
|
|
1279
1545
|
ppid,
|
|
1280
1546
|
flags,
|
|
1281
1547
|
stream,
|
|
@@ -1283,20 +1549,6 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
|
|
|
1283
1549
|
context
|
|
1284
1550
|
);
|
|
1285
1551
|
}
|
|
1286
|
-
#else
|
|
1287
|
-
num_bytes = (ssize_t)sctp_sendmsg(
|
|
1288
|
-
fileno,
|
|
1289
|
-
StringValueCStr(v_msg),
|
|
1290
|
-
RSTRING_LEN(v_msg),
|
|
1291
|
-
(struct sockaddr*)addrs,
|
|
1292
|
-
size,
|
|
1293
|
-
ppid,
|
|
1294
|
-
flags,
|
|
1295
|
-
stream,
|
|
1296
|
-
ttl,
|
|
1297
|
-
context
|
|
1298
|
-
);
|
|
1299
|
-
#endif
|
|
1300
1552
|
|
|
1301
1553
|
if(num_bytes < 0){
|
|
1302
1554
|
#ifdef BSD
|
|
@@ -1369,6 +1621,8 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
|
|
|
1369
1621
|
if(buffer == NULL)
|
|
1370
1622
|
rb_raise(rb_eNoMemError, "failed to allocate buffer");
|
|
1371
1623
|
|
|
1624
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1625
|
+
|
|
1372
1626
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1373
1627
|
length = sizeof(struct sockaddr_in);
|
|
1374
1628
|
|
|
@@ -1443,6 +1697,8 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
|
|
|
1443
1697
|
|
|
1444
1698
|
bzero(&initmsg, sizeof(initmsg));
|
|
1445
1699
|
|
|
1700
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1701
|
+
|
|
1446
1702
|
v_output = rb_hash_aref2(v_options, "output_streams");
|
|
1447
1703
|
v_input = rb_hash_aref2(v_options, "input_streams");
|
|
1448
1704
|
v_attempts = rb_hash_aref2(v_options, "max_attempts");
|
|
@@ -1513,6 +1769,8 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
|
|
|
1513
1769
|
bzero(&events, sizeof(events));
|
|
1514
1770
|
Check_Type(v_options, T_HASH);
|
|
1515
1771
|
|
|
1772
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1773
|
+
|
|
1516
1774
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1517
1775
|
|
|
1518
1776
|
if(RTEST(rb_hash_aref2(v_options, "data_io")))
|
|
@@ -1593,6 +1851,8 @@ static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
|
|
|
1593
1851
|
if(backlog > SOMAXCONN)
|
|
1594
1852
|
rb_raise(rb_eArgError, "backlog value exceeds maximum value of: %i", SOMAXCONN);
|
|
1595
1853
|
|
|
1854
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1855
|
+
|
|
1596
1856
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1597
1857
|
|
|
1598
1858
|
if(listen(fileno, backlog) < 0)
|
|
@@ -1623,6 +1883,8 @@ static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
|
|
|
1623
1883
|
int fileno, assoc_fileno;
|
|
1624
1884
|
sctp_assoc_t assoc_id;
|
|
1625
1885
|
|
|
1886
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1887
|
+
|
|
1626
1888
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1627
1889
|
assoc_id = NUM2INT(v_assoc_id);
|
|
1628
1890
|
|
|
@@ -1660,6 +1922,8 @@ static VALUE rsctp_get_default_send_params(VALUE self){
|
|
|
1660
1922
|
|
|
1661
1923
|
bzero(&sndrcv, sizeof(sndrcv));
|
|
1662
1924
|
|
|
1925
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1926
|
+
|
|
1663
1927
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1664
1928
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
1665
1929
|
size = sizeof(struct sctp_sndrcvinfo);
|
|
@@ -1705,6 +1969,8 @@ static VALUE rsctp_get_association_info(VALUE self){
|
|
|
1705
1969
|
|
|
1706
1970
|
bzero(&assoc, sizeof(assoc));
|
|
1707
1971
|
|
|
1972
|
+
CHECK_SOCKET_CLOSED(self);
|
|
1973
|
+
|
|
1708
1974
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1709
1975
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
1710
1976
|
size = sizeof(struct sctp_assocparams);
|
|
@@ -1747,6 +2013,8 @@ static VALUE rsctp_set_association_info(VALUE self, VALUE v_options){
|
|
|
1747
2013
|
|
|
1748
2014
|
bzero(&assoc, sizeof(assoc));
|
|
1749
2015
|
|
|
2016
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2017
|
+
|
|
1750
2018
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1751
2019
|
|
|
1752
2020
|
v_assoc_id = rb_hash_aref2(v_options, "association_id");
|
|
@@ -1811,6 +2079,8 @@ static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
|
|
|
1811
2079
|
int how, fileno;
|
|
1812
2080
|
VALUE v_how;
|
|
1813
2081
|
|
|
2082
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2083
|
+
|
|
1814
2084
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1815
2085
|
|
|
1816
2086
|
rb_scan_args(argc, argv, "01", &v_how);
|
|
@@ -1850,6 +2120,8 @@ static VALUE rsctp_get_retransmission_info(VALUE self){
|
|
|
1850
2120
|
|
|
1851
2121
|
bzero(&rto, sizeof(rto));
|
|
1852
2122
|
|
|
2123
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2124
|
+
|
|
1853
2125
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1854
2126
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
1855
2127
|
size = sizeof(struct sctp_rtoinfo);
|
|
@@ -1889,6 +2161,8 @@ static VALUE rsctp_set_retransmission_info(VALUE self, VALUE v_options){
|
|
|
1889
2161
|
|
|
1890
2162
|
bzero(&rto, sizeof(rto));
|
|
1891
2163
|
|
|
2164
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2165
|
+
|
|
1892
2166
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1893
2167
|
|
|
1894
2168
|
v_assoc_id = rb_hash_aref2(v_options, "association_id");
|
|
@@ -1954,10 +2228,12 @@ static VALUE rsctp_get_status(VALUE self){
|
|
|
1954
2228
|
sctp_assoc_t assoc_id;
|
|
1955
2229
|
struct sctp_status status;
|
|
1956
2230
|
struct sctp_paddrinfo* spinfo;
|
|
1957
|
-
char tmpname[
|
|
2231
|
+
char tmpname[INET6_ADDRSTRLEN];
|
|
1958
2232
|
|
|
1959
2233
|
bzero(&status, sizeof(status));
|
|
1960
2234
|
|
|
2235
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2236
|
+
|
|
1961
2237
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
1962
2238
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
1963
2239
|
size = sizeof(struct sctp_status);
|
|
@@ -2022,6 +2298,8 @@ static VALUE rsctp_get_subscriptions(VALUE self){
|
|
|
2022
2298
|
|
|
2023
2299
|
bzero(&events, sizeof(events));
|
|
2024
2300
|
|
|
2301
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2302
|
+
|
|
2025
2303
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2026
2304
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2027
2305
|
size = sizeof(struct sctp_event_subscribe);
|
|
@@ -2087,6 +2365,8 @@ static VALUE rsctp_get_peer_address_params(VALUE self){
|
|
|
2087
2365
|
bzero(&paddr, sizeof(paddr));
|
|
2088
2366
|
bzero(&str, sizeof(str));
|
|
2089
2367
|
|
|
2368
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2369
|
+
|
|
2090
2370
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2091
2371
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2092
2372
|
size = sizeof(struct sctp_paddrparams);
|
|
@@ -2094,7 +2374,18 @@ static VALUE rsctp_get_peer_address_params(VALUE self){
|
|
|
2094
2374
|
if(sctp_opt_info(fileno, assoc_id, SCTP_PEER_ADDR_PARAMS, (void*)&paddr, &size) < 0)
|
|
2095
2375
|
rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
|
|
2096
2376
|
|
|
2097
|
-
|
|
2377
|
+
{
|
|
2378
|
+
struct sockaddr* sa = (struct sockaddr*)&paddr.spp_address;
|
|
2379
|
+
|
|
2380
|
+
if(sa->sa_family == AF_INET6){
|
|
2381
|
+
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
|
2382
|
+
inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
|
|
2383
|
+
}
|
|
2384
|
+
else{
|
|
2385
|
+
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
|
2386
|
+
inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2098
2389
|
|
|
2099
2390
|
return rb_struct_new(
|
|
2100
2391
|
v_sctp_peer_addr_params_struct,
|
|
@@ -2134,6 +2425,8 @@ static VALUE rsctp_get_init_msg(VALUE self){
|
|
|
2134
2425
|
|
|
2135
2426
|
bzero(&initmsg, sizeof(initmsg));
|
|
2136
2427
|
|
|
2428
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2429
|
+
|
|
2137
2430
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2138
2431
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2139
2432
|
size = sizeof(struct sctp_initmsg);
|
|
@@ -2162,6 +2455,8 @@ static VALUE rsctp_get_nodelay(VALUE self){
|
|
|
2162
2455
|
sctp_assoc_t assoc_id;
|
|
2163
2456
|
int value;
|
|
2164
2457
|
|
|
2458
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2459
|
+
|
|
2165
2460
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2166
2461
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2167
2462
|
size = sizeof(int);
|
|
@@ -2188,6 +2483,8 @@ static VALUE rsctp_set_nodelay(VALUE self, VALUE v_bool){
|
|
|
2188
2483
|
socklen_t size;
|
|
2189
2484
|
int value;
|
|
2190
2485
|
|
|
2486
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2487
|
+
|
|
2191
2488
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2192
2489
|
size = sizeof(int);
|
|
2193
2490
|
|
|
@@ -2221,6 +2518,8 @@ static VALUE rsctp_disable_fragments(VALUE self, VALUE v_bool){
|
|
|
2221
2518
|
sctp_assoc_t assoc_id;
|
|
2222
2519
|
int value;
|
|
2223
2520
|
|
|
2521
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2522
|
+
|
|
2224
2523
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2225
2524
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2226
2525
|
size = sizeof(int);
|
|
@@ -2252,6 +2551,8 @@ static VALUE rsctp_get_autoclose(VALUE self){
|
|
|
2252
2551
|
sctp_assoc_t assoc_id;
|
|
2253
2552
|
int value;
|
|
2254
2553
|
|
|
2554
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2555
|
+
|
|
2255
2556
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2256
2557
|
assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
|
|
2257
2558
|
size = sizeof(int);
|
|
@@ -2288,6 +2589,8 @@ static VALUE rsctp_set_autoclose(VALUE self, VALUE v_seconds){
|
|
|
2288
2589
|
int fileno;
|
|
2289
2590
|
int value;
|
|
2290
2591
|
|
|
2592
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2593
|
+
|
|
2291
2594
|
value = NUM2INT(v_seconds);
|
|
2292
2595
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2293
2596
|
|
|
@@ -2399,7 +2702,7 @@ static VALUE rsctp_set_shared_key(int argc, VALUE* argv, VALUE self){
|
|
|
2399
2702
|
size_t len;
|
|
2400
2703
|
char* key;
|
|
2401
2704
|
uint keynum;
|
|
2402
|
-
|
|
2705
|
+
size_t size;
|
|
2403
2706
|
sctp_assoc_t assoc_id;
|
|
2404
2707
|
struct sctp_authkey* auth_key;
|
|
2405
2708
|
VALUE v_key, v_keynumber, v_assoc_id;
|
|
@@ -2460,6 +2763,8 @@ static VALUE rsctp_get_active_shared_key(int argc, VALUE* argv, VALUE self){
|
|
|
2460
2763
|
|
|
2461
2764
|
rb_scan_args(argc, argv, "11", &v_keynum, &v_assoc_id);
|
|
2462
2765
|
|
|
2766
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2767
|
+
|
|
2463
2768
|
bzero(&authkey, sizeof(authkey));
|
|
2464
2769
|
|
|
2465
2770
|
// Cast it later, we want to force a validity check.
|
|
@@ -2518,6 +2823,8 @@ static VALUE rsctp_set_active_shared_key(int argc, VALUE* argv, VALUE self){
|
|
|
2518
2823
|
|
|
2519
2824
|
rb_scan_args(argc, argv, "11", &v_keynum, &v_assoc_id);
|
|
2520
2825
|
|
|
2826
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2827
|
+
|
|
2521
2828
|
keynum = FIX2INT(v_keynum);
|
|
2522
2829
|
|
|
2523
2830
|
if(keynum < 0)
|
|
@@ -2614,6 +2921,8 @@ static VALUE rsctp_delete_shared_key(int argc, VALUE* argv, VALUE self){
|
|
|
2614
2921
|
static VALUE rsctp_map_ipv4(VALUE self, VALUE v_bool){
|
|
2615
2922
|
int fileno, boolean;
|
|
2616
2923
|
|
|
2924
|
+
CHECK_SOCKET_CLOSED(self);
|
|
2925
|
+
|
|
2617
2926
|
boolean = 0;
|
|
2618
2927
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2619
2928
|
|
|
@@ -2688,6 +2997,8 @@ static VALUE rsctp_set_default_send_params(VALUE self, VALUE v_options){
|
|
|
2688
2997
|
|
|
2689
2998
|
bzero(&sndrcv, sizeof(sndrcv));
|
|
2690
2999
|
|
|
3000
|
+
CHECK_SOCKET_CLOSED(self);
|
|
3001
|
+
|
|
2691
3002
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
2692
3003
|
|
|
2693
3004
|
v_stream = rb_hash_aref2(v_options, "stream");
|
|
@@ -2771,17 +3082,19 @@ static VALUE rsctp_set_default_send_params(VALUE self, VALUE v_options){
|
|
|
2771
3082
|
*/
|
|
2772
3083
|
static VALUE rsctp_set_peer_address_params(VALUE self, VALUE v_options){
|
|
2773
3084
|
VALUE v_assoc_id, v_address, v_hbinterval, v_pathmaxrxt, v_pathmtu, v_flags, v_ipv6_flowlabel;
|
|
2774
|
-
int fileno;
|
|
3085
|
+
int fileno, domain;
|
|
2775
3086
|
sctp_assoc_t assoc_id;
|
|
2776
3087
|
struct sctp_paddrparams paddr;
|
|
2777
|
-
struct sockaddr_in* sin;
|
|
2778
3088
|
|
|
2779
3089
|
if(!RB_TYPE_P(v_options, T_HASH))
|
|
2780
3090
|
rb_raise(rb_eTypeError, "options must be a hash");
|
|
2781
3091
|
|
|
2782
3092
|
bzero(&paddr, sizeof(paddr));
|
|
2783
3093
|
|
|
3094
|
+
CHECK_SOCKET_CLOSED(self);
|
|
3095
|
+
|
|
2784
3096
|
fileno = NUM2INT(rb_iv_get(self, "@fileno"));
|
|
3097
|
+
domain = NUM2INT(rb_iv_get(self, "@domain"));
|
|
2785
3098
|
|
|
2786
3099
|
v_assoc_id = rb_hash_aref2(v_options, "association_id");
|
|
2787
3100
|
v_address = rb_hash_aref2(v_options, "address");
|
|
@@ -2797,12 +3110,28 @@ static VALUE rsctp_set_peer_address_params(VALUE self, VALUE v_options){
|
|
|
2797
3110
|
assoc_id = NUM2INT(v_assoc_id);
|
|
2798
3111
|
paddr.spp_assoc_id = assoc_id;
|
|
2799
3112
|
|
|
2800
|
-
// If address is provided, set up the sockaddr structure
|
|
3113
|
+
// If address is provided, set up the sockaddr structure based on domain
|
|
2801
3114
|
if(!NIL_P(v_address)){
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
if(
|
|
2805
|
-
|
|
3115
|
+
const char* addr_str = StringValueCStr(v_address);
|
|
3116
|
+
|
|
3117
|
+
if(domain == AF_INET6){
|
|
3118
|
+
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&paddr.spp_address;
|
|
3119
|
+
sin6->sin6_family = AF_INET6;
|
|
3120
|
+
if(inet_pton(AF_INET6, addr_str, &sin6->sin6_addr) <= 0)
|
|
3121
|
+
rb_raise(rb_eArgError, "invalid IPv6 address: %s", addr_str);
|
|
3122
|
+
#ifdef BSD
|
|
3123
|
+
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
|
3124
|
+
#endif
|
|
3125
|
+
}
|
|
3126
|
+
else{
|
|
3127
|
+
struct sockaddr_in* sin = (struct sockaddr_in*)&paddr.spp_address;
|
|
3128
|
+
sin->sin_family = AF_INET;
|
|
3129
|
+
if(inet_pton(AF_INET, addr_str, &sin->sin_addr) <= 0)
|
|
3130
|
+
rb_raise(rb_eArgError, "invalid IPv4 address: %s", addr_str);
|
|
3131
|
+
#ifdef BSD
|
|
3132
|
+
sin->sin_len = sizeof(struct sockaddr_in);
|
|
3133
|
+
#endif
|
|
3134
|
+
}
|
|
2806
3135
|
}
|
|
2807
3136
|
|
|
2808
3137
|
if(!NIL_P(v_hbinterval))
|
|
@@ -2920,7 +3249,7 @@ void Init_socket(void){
|
|
|
2920
3249
|
|
|
2921
3250
|
v_sctp_receive_info_struct = rb_struct_define(
|
|
2922
3251
|
"ReceiveInfo", "message", "sid", "ssn", "flags", "ppid", "tsn",
|
|
2923
|
-
"cumtsn", "context", "
|
|
3252
|
+
"cumtsn", "context", "association_id", NULL
|
|
2924
3253
|
);
|
|
2925
3254
|
|
|
2926
3255
|
v_sctp_peer_addr_params_struct = rb_struct_define(
|
|
@@ -2993,8 +3322,8 @@ void Init_socket(void){
|
|
|
2993
3322
|
rb_define_attr(cSocket, "association_id", 1, 1);
|
|
2994
3323
|
rb_define_attr(cSocket, "port", 1, 1);
|
|
2995
3324
|
|
|
2996
|
-
/* 0.2.
|
|
2997
|
-
rb_define_const(cSocket, "VERSION", rb_str_new2("0.2.
|
|
3325
|
+
/* 0.2.2: The version of this library */
|
|
3326
|
+
rb_define_const(cSocket, "VERSION", rb_str_new2("0.2.2"));
|
|
2998
3327
|
|
|
2999
3328
|
/* send flags */
|
|
3000
3329
|
|
data/sctp-socket.gemspec
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sctp-socket
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Berger
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain:
|
|
11
10
|
- |
|
|
@@ -35,7 +34,7 @@ cert_chain:
|
|
|
35
34
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
|
36
35
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
|
37
36
|
-----END CERTIFICATE-----
|
|
38
|
-
date:
|
|
37
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
39
38
|
dependencies:
|
|
40
39
|
- !ruby/object:Gem::Dependency
|
|
41
40
|
name: bundler
|
|
@@ -132,7 +131,6 @@ metadata:
|
|
|
132
131
|
wiki_uri: https://github.com/djberg96/sctp-socket/wiki
|
|
133
132
|
rubygems_mfa_required: 'true'
|
|
134
133
|
funding_uri: https://github.com/sponsors/djberg96
|
|
135
|
-
post_install_message:
|
|
136
134
|
rdoc_options: []
|
|
137
135
|
require_paths:
|
|
138
136
|
- lib
|
|
@@ -147,8 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
147
145
|
- !ruby/object:Gem::Version
|
|
148
146
|
version: '0'
|
|
149
147
|
requirements: []
|
|
150
|
-
rubygems_version: 3.
|
|
151
|
-
signing_key:
|
|
148
|
+
rubygems_version: 3.6.9
|
|
152
149
|
specification_version: 4
|
|
153
150
|
summary: Ruby bindings for SCTP sockets
|
|
154
151
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|