sctp-socket 0.0.6 → 0.1.0

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