sctp-socket 0.0.1 → 0.0.5

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: c30fa4f2df555124cafe30c8440c3429b977d0d6dce57b46fbaee7510c096cb4
4
- data.tar.gz: 0e008c97688b85e1a2fc27b2af11a5a6262fd755f49aa762e7d6c78fea9ca863
3
+ metadata.gz: 319cf8cad773727889aed0c51508d4febfa4e145f9572ef2cdc265bdfc4c6ef2
4
+ data.tar.gz: aa085297b675c4f8a1468d689868a25ff6e9b9f5c954324801146b3878bdb150
5
5
  SHA512:
6
- metadata.gz: 4f42d5408ad8262084b6df0e6fd199a9dd142fb806f7b603c64a117fd31e2c890ba4090d9c1e04b5491d84e9fb8a77f7d6bc4b39d2da30e982b4fe9d5c17b0a3
7
- data.tar.gz: 881f42f26d2f080e2962e9ca01ea179b53ebd13bd956d42b44e626613d7f383208f250c7fb621ae9bddcf3bc95de544db63d08767a70a77d68c1c9bf3205ae75
6
+ metadata.gz: a26f8069a0034447ceadd4bb5e59af079da161e4ed0d2620de9df1809e072284fa2fc7aea0799f8f1d17f2da74de744ebc4fec399f21f93e0afa713092b5e0ca
7
+ data.tar.gz: 5267896027a79534c91c52396528654a9f046437ccf437be392d1609fbee72980cfd18116db8e85453048976a990084321089d6159822a5453d4ba155163581f
checksums.yaml.gz.sig CHANGED
Binary file
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  *.log
4
4
  *.lock
5
5
  Makefile
6
+ tmp/
data/CHANGES.md CHANGED
@@ -1,3 +1,24 @@
1
- ## 24-Nov-2020
1
+ ## 0.0.5 - 15-Dec-2021
2
+ * Add handling for Linux platforms that don't support the sctp_sendv function
3
+ and/or the SCTP_SEND_FAILED_EVENT notification.
4
+ * Some minor updates to Rakefile and Gemfile.
2
5
 
6
+ ## 0.0.4 - 3-Dec-2020
7
+ * Added the send method. Use this when you already have a connection.
8
+ * Fixed a flags bug in the sendmsg method.
9
+ * Fixed an association_id typo in the connect method.
10
+ * The SCTP_PR_SCTP_TTL flag is automatically set if a TTL value is provided.
11
+ * Added some constants so you can actually start passing flag values.
12
+
13
+ ## 0.0.3 - 1-Dec-2020
14
+ * Added notification hooks that you can subscribe to, so now the subscribe method
15
+ actually does something.
16
+
17
+ ## 0.0.2 - 29-Nov-2020
18
+ * Fixed the homepage link in the gemspec metadata. Thanks go to Nick LaMuro for the patch.
19
+ * The getlocalnames and getpeernames now return an array of addresses.
20
+ * Added a shutdown method.
21
+ * Added more documentation.
22
+
23
+ ## 0.0.1 - 24-Nov-2020
3
24
  * Initial release.
data/Gemfile CHANGED
@@ -1,10 +1,2 @@
1
- source 'https://rubygems.org' do
2
- group 'test' do
3
- gem 'rake'
4
- gem 'rspec', '~> 3.9'
5
- end
6
-
7
- group 'development' do
8
- gem 'rake-compiler', '~> 1.1'
9
- end
10
- end
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md CHANGED
@@ -12,7 +12,7 @@ On some systems, such as RHEL8, you may need to enable the sctp module.
12
12
 
13
13
  ## Installation
14
14
 
15
- `gem install sctp-socket`
15
+ `gem install sctp-socket`
16
16
 
17
17
  ## About SCTP
18
18
 
@@ -30,7 +30,7 @@ is applied to correct loss or corruption of data.
30
30
 
31
31
  ## Synopsis
32
32
 
33
- ```
33
+ ```ruby
34
34
  # sample_server.rb
35
35
  require 'sctp/socket'
36
36
 
@@ -43,7 +43,7 @@ begin
43
43
  socket.listen
44
44
 
45
45
  while true
46
- data = socket.recvmsgx
46
+ data = socket.recvmsg
47
47
  puts data
48
48
  end
49
49
  ensure
@@ -53,15 +53,28 @@ end
53
53
 
54
54
  ## Future Plans
55
55
 
56
- * Check for notification data and return it if encountered.
57
- * Add specs.
56
+ * Add more constants.
57
+ * Add more specs.
58
+ * Add more notifications.
58
59
 
59
60
  ## Known Issues
60
61
 
62
+ Currently this has only been developed and tested on Linux. Other platforms
63
+ will probably only be supported via community contributions.
64
+
65
+ On Ubuntu 20 and possibly other Linux variants, the sendv method is not
66
+ available. Use the sendmsg method instead.
67
+
61
68
  Please report any issues on the github project page.
62
69
 
63
70
  https://github.com/djberg96/sctp-socket
64
71
 
72
+ ## More Information on SCTP
73
+
74
+ * https://www.linuxjournal.com/article/9748
75
+ * https://www.linuxjournal.com/article/9749
76
+ * https://www.linuxjournal.com/article/9784
77
+
65
78
  ## License
66
79
 
67
80
  Apache-2.0
data/Rakefile CHANGED
@@ -6,20 +6,21 @@ require 'rake/extensiontask'
6
6
  include RbConfig
7
7
 
8
8
  CLEAN.include(
9
- '**/*.gem', # Gem files
10
- '**/*.rbc', # Rubinius
11
- '**/*.o', # C object file
12
- '**/*.log', # Ruby extension build log
13
- '**/Makefile', # C Makefile
14
- '**/conftest.dSYM', # OS X build directory
15
- "**/*.#{CONFIG['DLEXT']}" # C shared object
9
+ '**/*.gem', # Gem files
10
+ '**/*.rbc', # Rubinius
11
+ '**/*.o', # C object file
12
+ '**/*.log', # Ruby extension build log
13
+ '**/Makefile', # C Makefile
14
+ '**/conftest.dSYM', # OS X build directory
15
+ "**/*.#{CONFIG['DLEXT']}", # C shared object
16
+ 'tmp' # Rake compiler
16
17
  )
17
18
 
18
19
  namespace :gem do
19
20
  desc "Create the sys-uname gem"
20
21
  task :create => [:clean] do
21
22
  require 'rubygems/package'
22
- spec = eval(IO.read('sctp-socket.gemspec'))
23
+ spec = Gem::Specification.load('sctp-socket.gemspec')
23
24
  spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
24
25
  Gem::Package.build(spec)
25
26
  end
@@ -39,4 +40,4 @@ end
39
40
  RSpec::Core::RakeTask.new
40
41
 
41
42
  task :spec => :compile
42
- task :default => :spec
43
+ task :default => [:clean, :spec]
data/ext/sctp/extconf.rb CHANGED
@@ -2,4 +2,6 @@ require 'mkmf'
2
2
 
3
3
  have_header('netinet/sctp.h')
4
4
  have_library('sctp')
5
+ have_func('sctp_sendv', 'netinet/sctp.h')
6
+ have_struct_member('struct sctp_event_subscribe', 'sctp_send_failure_event', 'netinet/sctp.h')
5
7
  create_makefile('sctp/socket')
data/ext/sctp/socket.c CHANGED
@@ -7,6 +7,61 @@
7
7
  VALUE mSCTP;
8
8
  VALUE cSocket;
9
9
  VALUE v_sndrcv_struct;
10
+ VALUE v_assoc_change_struct;
11
+ VALUE v_peeraddr_change_struct;
12
+ VALUE v_remote_error_struct;
13
+ VALUE v_send_failed_event_struct;
14
+ VALUE v_shutdown_event_struct;
15
+ VALUE v_sndinfo_struct;
16
+ VALUE v_adaptation_event_struct;
17
+ VALUE v_partial_delivery_event_struct;
18
+ VALUE v_auth_event_struct;
19
+ VALUE v_sockaddr_in_struct;
20
+ VALUE v_sctp_status_struct;
21
+ VALUE v_sctp_rtoinfo_struct;
22
+ VALUE v_sctp_associnfo_struct;
23
+ VALUE v_sctp_default_send_params_struct;
24
+
25
+ #if !defined(IOV_MAX)
26
+ #if defined(_SC_IOV_MAX)
27
+ #define IOV_MAX (sysconf(_SC_IOV_MAX))
28
+ #else
29
+ // Assume infinity, or let the syscall return with error
30
+ #define IOV_MAX INT_MAX
31
+ #endif
32
+ #endif
33
+
34
+ #define ARY2IOVEC(iov,ary) \
35
+ do { \
36
+ VALUE *cur; \
37
+ struct iovec *tmp; \
38
+ long n; \
39
+ cur = RARRAY_PTR(ary); \
40
+ n = RARRAY_LEN(ary); \
41
+ iov = tmp = alloca(sizeof(struct iovec) * n); \
42
+ for (; --n >= 0; tmp++, cur++) { \
43
+ if (TYPE(*cur) != T_STRING) \
44
+ rb_raise(rb_eArgError, "must be an array of strings"); \
45
+ tmp->iov_base = RSTRING_PTR(*cur); \
46
+ tmp->iov_len = RSTRING_LEN(*cur); \
47
+ } \
48
+ } while (0)
49
+
50
+ // TODO: Yes, I know I need to update the signature.
51
+ VALUE convert_sockaddr_in_to_struct(struct sockaddr_in* addr){
52
+ char ipbuf[INET6_ADDRSTRLEN];
53
+
54
+ if(addr->sin_family == AF_INET6)
55
+ inet_ntop(addr->sin_family, &(((struct sockaddr_in6 *)addr)->sin6_addr), ipbuf, sizeof(ipbuf));
56
+ else
57
+ inet_ntop(addr->sin_family, &(((struct sockaddr_in *)addr)->sin_addr), ipbuf, sizeof(ipbuf));
58
+
59
+ return rb_struct_new(v_sockaddr_in_struct,
60
+ INT2NUM(addr->sin_family),
61
+ INT2NUM(ntohs(addr->sin_port)),
62
+ rb_str_new2(ipbuf)
63
+ );
64
+ }
10
65
 
11
66
  // Helper function to get a hash value via string or symbol.
12
67
  VALUE rb_hash_aref2(VALUE v_hash, const char* key){
@@ -26,8 +81,15 @@ VALUE rb_hash_aref2(VALUE v_hash, const char* key){
26
81
  * a domain (aka family) value and socket type. By default these are AF_INET
27
82
  * and SOCK_SEQPACKET, respectively.
28
83
  *
84
+ * There are only two supported families: SOCK_SEQPACKET for the creation
85
+ * of a one-to-many socket, and SOCK_STREAM for the creation of a
86
+ * one-to-one socket.
87
+ *
29
88
  * Example:
30
89
  *
90
+ * require 'socket'
91
+ * require 'sctp/socket'
92
+ *
31
93
  * socket1 = SCTP::Socket.new
32
94
  * socket2 = SCTP::Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
33
95
  */
@@ -193,7 +255,7 @@ static VALUE rsctp_connect(int argc, VALUE* argv, VALUE self){
193
255
  if(sctp_connectx(sock_fd, (struct sockaddr *) addrs, num_ip, &assoc) < 0)
194
256
  rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
195
257
 
196
- rb_iv_set(self, "@assocation_id", INT2NUM(assoc));
258
+ rb_iv_set(self, "@association_id", INT2NUM(assoc));
197
259
 
198
260
  return self;
199
261
  }
@@ -215,16 +277,20 @@ static VALUE rsctp_close(VALUE self){
215
277
  return self;
216
278
  }
217
279
 
280
+ /*
281
+ * Return an array of all addresses of a peer.
282
+ */
218
283
  static VALUE rsctp_getpeernames(VALUE self){
219
- VALUE v_assoc_id = rb_iv_get(self, "@assocation_id");
220
284
  sctp_assoc_t assoc_id;
221
285
  struct sockaddr* addrs;
222
286
  int i, sock_fd, num_addrs;
287
+ char str[16];
288
+ VALUE v_array = rb_ary_new();
223
289
 
224
290
  bzero(&addrs, sizeof(addrs));
225
291
 
226
292
  sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
227
- assoc_id = NUM2INT(v_assoc_id);
293
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
228
294
 
229
295
  num_addrs = sctp_getpaddrs(sock_fd, assoc_id, &addrs);
230
296
 
@@ -234,23 +300,36 @@ static VALUE rsctp_getpeernames(VALUE self){
234
300
  }
235
301
 
236
302
  for(i = 0; i < num_addrs; i++){
237
- // TODO: Create and return array of IpAddr objects
303
+ inet_ntop(AF_INET, &(((struct sockaddr_in *)&addrs[i])->sin_addr), str, sizeof(str));
304
+ rb_ary_push(v_array, rb_str_new2(str));
305
+ bzero(&str, sizeof(str));
238
306
  }
239
307
 
240
308
  sctp_freepaddrs(addrs);
241
309
 
242
- return self;
310
+ return v_array;
243
311
  }
244
312
 
313
+ /*
314
+ * Return an array of local addresses that are part of the association.
315
+ *
316
+ * Example:
317
+ *
318
+ * socket = SCTP::Socket.new
319
+ * socket.bind(:addresses => ['10.0.4.5', '10.0.5.5'])
320
+ * socket.getlocalnames # => ['10.0.4.5', '10.0.5.5'])
321
+ */
245
322
  static VALUE rsctp_getlocalnames(VALUE self){
246
323
  sctp_assoc_t assoc_id;
247
324
  struct sockaddr* addrs;
248
325
  int i, sock_fd, num_addrs;
326
+ char str[16];
327
+ VALUE v_array = rb_ary_new();
249
328
 
250
329
  bzero(&addrs, sizeof(addrs));
251
330
 
252
331
  sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
253
- assoc_id = NUM2INT(rb_iv_get(self, "@assocation_id"));
332
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
254
333
 
255
334
  num_addrs = sctp_getladdrs(sock_fd, assoc_id, &addrs);
256
335
 
@@ -260,12 +339,152 @@ static VALUE rsctp_getlocalnames(VALUE self){
260
339
  }
261
340
 
262
341
  for(i = 0; i < num_addrs; i++){
263
- // TODO: Create and return array of IpAddr objects
342
+ inet_ntop(AF_INET, &(((struct sockaddr_in *)&addrs[i])->sin_addr), str, sizeof(str));
343
+ rb_ary_push(v_array, rb_str_new2(str));
344
+ bzero(&str, sizeof(str));
264
345
  }
265
346
 
266
347
  sctp_freeladdrs(addrs);
267
348
 
268
- return self;
349
+ return v_array;
350
+ }
351
+
352
+ #ifdef HAVE_SCTP_SENDV
353
+ static VALUE rsctp_sendv(VALUE self, VALUE v_messages){
354
+ struct iovec* iov;
355
+ struct sockaddr* addrs[8];
356
+ struct sctp_sndinfo info;
357
+ int sock_fd, num_bytes, size;
358
+
359
+ Check_Type(v_messages, T_ARRAY);
360
+ bzero(&addrs, sizeof(addrs));
361
+
362
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
363
+
364
+ Check_Type(v_messages, T_ARRAY);
365
+ size = RARRAY_LEN(v_messages);
366
+
367
+ if(!size)
368
+ rb_raise(rb_eArgError, "Must contain at least one message");
369
+
370
+ if(size > IOV_MAX)
371
+ rb_raise(rb_eArgError, "Array size is greater than IOV_MAX");
372
+
373
+ ARY2IOVEC(iov, v_messages);
374
+
375
+ info.snd_flags = SCTP_UNORDERED;
376
+ info.snd_assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
377
+
378
+ num_bytes = sctp_sendv(
379
+ sock_fd,
380
+ iov,
381
+ size,
382
+ NULL,
383
+ 0,
384
+ &info,
385
+ sizeof(info),
386
+ SCTP_SENDV_SNDINFO,
387
+ 0
388
+ );
389
+
390
+ if(num_bytes < 0)
391
+ rb_raise(rb_eSystemCallError, "sctp_sendv: %s", strerror(errno));
392
+
393
+ return INT2NUM(num_bytes);
394
+ }
395
+ #endif
396
+
397
+ /*
398
+ * Send a message on an already-connected socket to a specific association.
399
+ *
400
+ * Example:
401
+ *
402
+ * socket = SCTP::Socket.new
403
+ * socket.connect(:port => 42000, :addresses => ['10.0.4.5', '10.0.5.5'])
404
+ *
405
+ * socket.send(:message => "Hello World")
406
+ * socket.send(:message => "Hello World", :association_id => 37)
407
+ *
408
+ */
409
+ static VALUE rsctp_send(VALUE self, VALUE v_options){
410
+ uint16_t stream;
411
+ uint32_t ppid, send_flags, ctrl_flags, ttl, context;
412
+ ssize_t num_bytes;
413
+ int sock_fd;
414
+ sctp_assoc_t assoc_id;
415
+ struct sctp_sndrcvinfo info;
416
+ VALUE v_msg, v_stream, v_ppid, v_context, v_send_flags, v_ctrl_flags, v_ttl, v_assoc_id;
417
+
418
+ Check_Type(v_options, T_HASH);
419
+
420
+ v_msg = rb_hash_aref2(v_options, "message");
421
+ v_stream = rb_hash_aref2(v_options, "stream");
422
+ v_ppid = rb_hash_aref2(v_options, "ppid");
423
+ v_context = rb_hash_aref2(v_options, "context");
424
+ v_send_flags = rb_hash_aref2(v_options, "send_flags");
425
+ v_ctrl_flags = rb_hash_aref2(v_options, "control_flags");
426
+ v_ttl = rb_hash_aref2(v_options, "ttl");
427
+ v_assoc_id = rb_hash_aref2(v_options, "association_id");
428
+
429
+ if(NIL_P(v_stream))
430
+ stream = 0;
431
+ else
432
+ stream = NUM2INT(v_stream);
433
+
434
+ if(NIL_P(v_send_flags))
435
+ send_flags = 0;
436
+ else
437
+ send_flags = NUM2INT(v_send_flags);
438
+
439
+ if(NIL_P(v_ctrl_flags))
440
+ ctrl_flags = 0;
441
+ else
442
+ ctrl_flags = NUM2INT(v_ctrl_flags);
443
+
444
+ if(NIL_P(v_ttl)){
445
+ ttl = 0;
446
+ }
447
+ else{
448
+ ttl = NUM2INT(v_ttl);
449
+ send_flags |= SCTP_PR_SCTP_TTL;
450
+ }
451
+
452
+ if(NIL_P(v_ppid))
453
+ ppid = 0;
454
+ else
455
+ ppid = NUM2INT(v_ppid);
456
+
457
+ if(NIL_P(v_context))
458
+ context = 0;
459
+ else
460
+ context = NUM2INT(v_context);
461
+
462
+ if(NIL_P(v_assoc_id))
463
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
464
+ else
465
+ assoc_id = NUM2INT(v_assoc_id);
466
+
467
+ info.sinfo_stream = stream;
468
+ info.sinfo_flags = send_flags;
469
+ info.sinfo_ppid = ppid;
470
+ info.sinfo_context = context;
471
+ info.sinfo_timetolive = ttl;
472
+ info.sinfo_assoc_id = assoc_id;
473
+
474
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
475
+
476
+ num_bytes = sctp_send(
477
+ sock_fd,
478
+ StringValueCStr(v_msg),
479
+ RSTRING_LEN(v_msg),
480
+ &info,
481
+ ctrl_flags
482
+ );
483
+
484
+ if(num_bytes < 0)
485
+ rb_raise(rb_eSystemCallError, "sctp_send: %s", strerror(errno));
486
+
487
+ return INT2NUM(num_bytes);
269
488
  }
270
489
 
271
490
  /*
@@ -323,12 +542,15 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
323
542
  if(NIL_P(v_flags))
324
543
  flags = 0;
325
544
  else
326
- flags = NUM2INT(v_stream);
545
+ flags = NUM2INT(v_flags);
327
546
 
328
- if(NIL_P(v_ttl))
547
+ if(NIL_P(v_ttl)){
329
548
  ttl = 0;
330
- else
549
+ }
550
+ else{
331
551
  ttl = NUM2INT(v_ttl);
552
+ flags |= SCTP_PR_SCTP_TTL;
553
+ }
332
554
 
333
555
  if(NIL_P(v_ppid))
334
556
  ppid = 0;
@@ -406,7 +628,7 @@ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
406
628
  * end
407
629
  */
408
630
  static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
409
- VALUE v_flags;
631
+ VALUE v_flags, v_notification, v_message;
410
632
  struct sctp_sndrcvinfo sndrcvinfo;
411
633
  struct sockaddr_in clientaddr;
412
634
  int flags, bytes, sock_fd;
@@ -437,49 +659,215 @@ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
437
659
  if(bytes < 0)
438
660
  rb_raise(rb_eSystemCallError, "sctp_recvmsg: %s", strerror(errno));
439
661
 
440
- // TODO: Check for MSG_NOTIFICATION, return different structs for events.
441
- /*
662
+ v_notification = Qnil;
663
+
442
664
  if(flags & MSG_NOTIFICATION){
665
+ uint32_t i;
666
+ char str[16];
443
667
  union sctp_notification* snp;
668
+ VALUE v_str;
669
+ VALUE* v_temp;
670
+
444
671
  snp = (union sctp_notification*)buffer;
445
672
 
446
- switch(snp->sn_type){
673
+ switch(snp->sn_header.sn_type){
447
674
  case SCTP_ASSOC_CHANGE:
675
+ switch(snp->sn_assoc_change.sac_state){
676
+ case SCTP_COMM_LOST:
677
+ v_str = rb_str_new2("comm lost");
678
+ break;
679
+ case SCTP_COMM_UP:
680
+ v_str = rb_str_new2("comm up");
681
+ break;
682
+ case SCTP_RESTART:
683
+ v_str = rb_str_new2("restart");
684
+ break;
685
+ case SCTP_SHUTDOWN_COMP:
686
+ v_str = rb_str_new2("shutdown complete");
687
+ break;
688
+ case SCTP_CANT_STR_ASSOC:
689
+ v_str = rb_str_new2("association setup failed");
690
+ break;
691
+ default:
692
+ v_str = rb_str_new2("unknown");
693
+ }
694
+
695
+ v_notification = rb_struct_new(v_assoc_change_struct,
696
+ UINT2NUM(snp->sn_assoc_change.sac_type),
697
+ UINT2NUM(snp->sn_assoc_change.sac_length),
698
+ UINT2NUM(snp->sn_assoc_change.sac_state),
699
+ UINT2NUM(snp->sn_assoc_change.sac_error),
700
+ UINT2NUM(snp->sn_assoc_change.sac_outbound_streams),
701
+ UINT2NUM(snp->sn_assoc_change.sac_inbound_streams),
702
+ UINT2NUM(snp->sn_assoc_change.sac_assoc_id),
703
+ v_str
704
+ );
448
705
  break;
449
706
  case SCTP_PEER_ADDR_CHANGE:
707
+ switch(snp->sn_paddr_change.spc_state){
708
+ case SCTP_ADDR_AVAILABLE:
709
+ v_str = rb_str_new2("available");
710
+ break;
711
+ case SCTP_ADDR_UNREACHABLE:
712
+ v_str = rb_str_new2("unreachable");
713
+ break;
714
+ case SCTP_ADDR_REMOVED:
715
+ v_str = rb_str_new2("removed from association");
716
+ break;
717
+ case SCTP_ADDR_ADDED:
718
+ v_str = rb_str_new2("added to association");
719
+ break;
720
+ case SCTP_ADDR_MADE_PRIM:
721
+ v_str = rb_str_new2("primary destination");
722
+ break;
723
+ default:
724
+ v_str = rb_str_new2("unknown");
725
+ }
726
+
727
+ inet_ntop(
728
+ ((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_family,
729
+ &(((struct sockaddr_in *)&snp->sn_paddr_change.spc_aaddr)->sin_addr),
730
+ str,
731
+ sizeof(str)
732
+ );
733
+
734
+ v_notification = rb_struct_new(v_peeraddr_change_struct,
735
+ UINT2NUM(snp->sn_paddr_change.spc_type),
736
+ UINT2NUM(snp->sn_paddr_change.spc_length),
737
+ rb_str_new2(str),
738
+ UINT2NUM(snp->sn_paddr_change.spc_state),
739
+ UINT2NUM(snp->sn_paddr_change.spc_error),
740
+ UINT2NUM(snp->sn_paddr_change.spc_assoc_id),
741
+ v_str
742
+ );
450
743
  break;
451
744
  case SCTP_REMOTE_ERROR:
745
+ v_temp = ALLOCA_N(VALUE, snp->sn_remote_error.sre_length);
746
+
747
+ for(i = 0; i < snp->sn_remote_error.sre_length; i++){
748
+ v_temp[i] = UINT2NUM(snp->sn_remote_error.sre_data[i]);
749
+ }
750
+
751
+ v_notification = rb_struct_new(v_remote_error_struct,
752
+ UINT2NUM(snp->sn_remote_error.sre_type),
753
+ UINT2NUM(snp->sn_remote_error.sre_length),
754
+ UINT2NUM(snp->sn_remote_error.sre_error),
755
+ UINT2NUM(snp->sn_remote_error.sre_assoc_id),
756
+ rb_ary_new4(snp->sn_remote_error.sre_length, v_temp)
757
+ );
758
+ break;
759
+ #ifdef SCTP_SEND_FAILED_EVENT
760
+ case SCTP_SEND_FAILED_EVENT:
761
+ v_temp = ALLOCA_N(VALUE, snp->sn_send_failed_event.ssf_length);
762
+
763
+ for(i = 0; i < snp->sn_send_failed_event.ssf_length; i++){
764
+ v_temp[i] = UINT2NUM(snp->sn_send_failed_event.ssf_data[i]);
765
+ }
766
+
767
+ v_notification = rb_struct_new(v_send_failed_event_struct,
768
+ UINT2NUM(snp->sn_send_failed_event.ssf_type),
769
+ UINT2NUM(snp->sn_send_failed_event.ssf_length),
770
+ UINT2NUM(snp->sn_send_failed_event.ssf_error),
771
+ rb_struct_new(v_sndinfo_struct,
772
+ UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_sid),
773
+ UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_flags),
774
+ UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_ppid),
775
+ UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_context),
776
+ UINT2NUM(snp->sn_send_failed_event.ssfe_info.snd_assoc_id)
777
+ ),
778
+ UINT2NUM(snp->sn_send_failed_event.ssf_assoc_id),
779
+ rb_ary_new4(snp->sn_send_failed_event.ssf_length, v_temp)
780
+ );
452
781
  break;
782
+ #else
453
783
  case SCTP_SEND_FAILED:
784
+ v_temp = ALLOCA_N(VALUE, snp->sn_send_failed.ssf_length);
785
+
786
+ for(i = 0; i < snp->sn_send_failed.ssf_length; i++){
787
+ v_temp[i] = UINT2NUM(snp->sn_send_failed.ssf_data[i]);
788
+ }
789
+
790
+ v_notification = rb_struct_new(v_send_failed_event_struct,
791
+ UINT2NUM(snp->sn_send_failed.ssf_type),
792
+ UINT2NUM(snp->sn_send_failed.ssf_length),
793
+ UINT2NUM(snp->sn_send_failed.ssf_error),
794
+ Qnil,
795
+ UINT2NUM(snp->sn_send_failed.ssf_assoc_id),
796
+ rb_ary_new4(snp->sn_send_failed.ssf_length, v_temp)
797
+ );
454
798
  break;
799
+ #endif
455
800
  case SCTP_SHUTDOWN_EVENT:
801
+ v_notification = rb_struct_new(v_shutdown_event_struct,
802
+ UINT2NUM(snp->sn_shutdown_event.sse_type),
803
+ UINT2NUM(snp->sn_shutdown_event.sse_length),
804
+ UINT2NUM(snp->sn_shutdown_event.sse_assoc_id)
805
+ );
456
806
  break;
457
807
  case SCTP_ADAPTATION_INDICATION:
808
+ v_notification = rb_struct_new(v_adaptation_event_struct,
809
+ UINT2NUM(snp->sn_adaptation_event.sai_type),
810
+ UINT2NUM(snp->sn_adaptation_event.sai_length),
811
+ UINT2NUM(snp->sn_adaptation_event.sai_adaptation_ind),
812
+ UINT2NUM(snp->sn_adaptation_event.sai_assoc_id)
813
+ );
458
814
  break;
459
815
  case SCTP_PARTIAL_DELIVERY_EVENT:
816
+ v_notification = rb_struct_new(v_partial_delivery_event_struct,
817
+ UINT2NUM(snp->sn_pdapi_event.pdapi_type),
818
+ UINT2NUM(snp->sn_pdapi_event.pdapi_length),
819
+ UINT2NUM(snp->sn_pdapi_event.pdapi_indication),
820
+ UINT2NUM(snp->sn_pdapi_event.pdapi_stream),
821
+ UINT2NUM(snp->sn_pdapi_event.pdapi_seq),
822
+ UINT2NUM(snp->sn_pdapi_event.pdapi_assoc_id)
823
+ );
824
+ break;
825
+ case SCTP_AUTHENTICATION_EVENT:
826
+ v_notification = rb_struct_new(v_auth_event_struct,
827
+ UINT2NUM(snp->sn_authkey_event.auth_type),
828
+ UINT2NUM(snp->sn_authkey_event.auth_length),
829
+ UINT2NUM(snp->sn_authkey_event.auth_keynumber),
830
+ UINT2NUM(snp->sn_authkey_event.auth_indication),
831
+ UINT2NUM(snp->sn_authkey_event.auth_assoc_id)
832
+ );
460
833
  break;
461
834
  }
462
835
  }
463
- */
836
+
837
+ if(NIL_P(v_notification))
838
+ v_message = rb_str_new(buffer, bytes);
839
+ else
840
+ v_message = Qnil;
464
841
 
465
842
  return rb_struct_new(v_sndrcv_struct,
466
- rb_str_new(buffer, bytes),
843
+ v_message,
467
844
  UINT2NUM(sndrcvinfo.sinfo_stream),
468
845
  UINT2NUM(sndrcvinfo.sinfo_flags),
469
846
  UINT2NUM(sndrcvinfo.sinfo_ppid),
470
847
  UINT2NUM(sndrcvinfo.sinfo_context),
471
848
  UINT2NUM(sndrcvinfo.sinfo_timetolive),
472
- UINT2NUM(sndrcvinfo.sinfo_assoc_id)
849
+ UINT2NUM(sndrcvinfo.sinfo_assoc_id),
850
+ v_notification,
851
+ convert_sockaddr_in_to_struct(&clientaddr)
473
852
  );
474
853
  }
475
854
 
476
855
  /*
477
- * {
478
- * :output_streams => 2,
479
- * :input_streams => 3,
480
- * :max_attempts => 5,
481
- * :timeout => 30
482
- * }
856
+ * Set the initial parameters used by the socket when sending out the INIT message.
857
+ *
858
+ * Example:
859
+ *
860
+ * socket = SCTP::Socket.new
861
+ * socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4, :timeout => 30)
862
+ *
863
+ * The following parameters can be configured:
864
+ *
865
+ * :output_streams - The number of outbound SCTP streams an application would like to request.
866
+ * :input_streams - The maximum number of inbound streams an application is prepared to allow.
867
+ * :max_attempts - How many times the the SCTP stack should send the initial INIT message before it's considered unreachable.
868
+ * :timeout - The maximum RTO value for the INIT timer.
869
+ *
870
+ * By default these values are set to zero (i.e. ignored).
483
871
  */
484
872
  static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
485
873
  int sock_fd;
@@ -519,7 +907,7 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
519
907
  * as follows:
520
908
  *
521
909
  * :association
522
- * - A change has occurred to an assocation, either a new one has begun or an existing one has end.
910
+ * - A change has occurred to an association, either a new one has begun or an existing one has end.
523
911
  *
524
912
  * :address
525
913
  * - The state of one of the peer's addresses has experienced a change.
@@ -530,14 +918,19 @@ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
530
918
  * :shutdown
531
919
  * - The peer has sent a shutdown to the local endpoint.
532
920
  *
921
+ * :data_io
922
+ * - Message data was received. On by default.
923
+ *
533
924
  * Others:
534
925
  *
535
- * :adaptation_layer
536
- * :authentication_event
537
- * :data_io
538
- * :peer_error
926
+ * :adaptation
927
+ * :authentication
539
928
  * :partial_delivery
929
+ *
930
+ * Not yet supported:
931
+ *
540
932
  * :sender_dry
933
+ * :peer_error
541
934
  *
542
935
  * By default only data_io is subscribed to.
543
936
  *
@@ -565,7 +958,11 @@ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
565
958
  events.sctp_address_event = 1;
566
959
 
567
960
  if(RTEST(rb_hash_aref2(v_options, "send_failure")))
961
+ #ifdef HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE_SCTP_SEND_FAILURE_EVENT
568
962
  events.sctp_send_failure_event = 1;
963
+ #else
964
+ events.sctp_send_failure_event_event = 1;
965
+ #endif
569
966
 
570
967
  if(RTEST(rb_hash_aref2(v_options, "peer_error")))
571
968
  events.sctp_peer_error_event = 1;
@@ -645,13 +1042,220 @@ static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
645
1042
  return self;
646
1043
  }
647
1044
 
1045
+ static VALUE rsctp_get_default_send_params(VALUE self){
1046
+ int sock_fd;
1047
+ socklen_t size;
1048
+ sctp_assoc_t assoc_id;
1049
+ struct sctp_sndrcvinfo sndrcv;
1050
+
1051
+ bzero(&sndrcv, sizeof(sndrcv));
1052
+
1053
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
1054
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
1055
+ size = sizeof(struct sctp_sndrcvinfo);
1056
+
1057
+ if(sctp_opt_info(sock_fd, assoc_id, SCTP_DEFAULT_SEND_PARAM, (void*)&sndrcv, &size) < 0)
1058
+ rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
1059
+
1060
+ return rb_struct_new(
1061
+ v_sctp_default_send_params_struct,
1062
+ INT2NUM(sndrcv.sinfo_stream),
1063
+ INT2NUM(sndrcv.sinfo_ssn),
1064
+ INT2NUM(sndrcv.sinfo_flags),
1065
+ INT2NUM(sndrcv.sinfo_ppid),
1066
+ INT2NUM(sndrcv.sinfo_context),
1067
+ INT2NUM(sndrcv.sinfo_timetolive),
1068
+ INT2NUM(sndrcv.sinfo_tsn),
1069
+ INT2NUM(sndrcv.sinfo_cumtsn),
1070
+ INT2NUM(sndrcv.sinfo_assoc_id)
1071
+ );
1072
+ }
1073
+
1074
+ static VALUE rsctp_get_association_info(VALUE self){
1075
+ int sock_fd;
1076
+ socklen_t size;
1077
+ sctp_assoc_t assoc_id;
1078
+ struct sctp_assocparams assoc;
1079
+
1080
+ bzero(&assoc, sizeof(assoc));
1081
+
1082
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
1083
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
1084
+ size = sizeof(struct sctp_assocparams);
1085
+
1086
+ if(sctp_opt_info(sock_fd, assoc_id, SCTP_ASSOCINFO, (void*)&assoc, &size) < 0)
1087
+ rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
1088
+
1089
+ return rb_struct_new(
1090
+ v_sctp_associnfo_struct,
1091
+ INT2NUM(assoc.sasoc_assoc_id),
1092
+ INT2NUM(assoc.sasoc_asocmaxrxt),
1093
+ INT2NUM(assoc.sasoc_number_peer_destinations),
1094
+ INT2NUM(assoc.sasoc_peer_rwnd),
1095
+ INT2NUM(assoc.sasoc_local_rwnd),
1096
+ INT2NUM(assoc.sasoc_cookie_life)
1097
+ );
1098
+ }
1099
+
1100
+ static VALUE rsctp_shutdown(int argc, VALUE* argv, VALUE self){
1101
+ int how, sock_fd;
1102
+ VALUE v_how;
1103
+
1104
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
1105
+
1106
+ rb_scan_args(argc, argv, "01", &v_how);
1107
+
1108
+ if(NIL_P(v_how)){
1109
+ how = SHUT_RDWR;
1110
+ }
1111
+ else{
1112
+ Check_Type(v_how, T_FIXNUM);
1113
+ how = NUM2INT(v_how);
1114
+ }
1115
+
1116
+ if(shutdown(sock_fd, how) < 0)
1117
+ rb_raise(rb_eSystemCallError, "shutdown: %s", strerror(errno));
1118
+
1119
+ return self;
1120
+ }
1121
+
1122
+ static VALUE rsctp_get_retransmission_info(VALUE self){
1123
+ int sock_fd;
1124
+ socklen_t size;
1125
+ sctp_assoc_t assoc_id;
1126
+ struct sctp_rtoinfo rto;
1127
+
1128
+ bzero(&rto, sizeof(rto));
1129
+
1130
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
1131
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
1132
+ size = sizeof(struct sctp_rtoinfo);
1133
+
1134
+ if(sctp_opt_info(sock_fd, assoc_id, SCTP_RTOINFO, (void*)&rto, &size) < 0)
1135
+ rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
1136
+
1137
+ return rb_struct_new(
1138
+ v_sctp_rtoinfo_struct,
1139
+ INT2NUM(rto.srto_assoc_id),
1140
+ INT2NUM(rto.srto_initial),
1141
+ INT2NUM(rto.srto_max),
1142
+ INT2NUM(rto.srto_min)
1143
+ );
1144
+ }
1145
+
1146
+ static VALUE rsctp_get_status(VALUE self){
1147
+ int sock_fd;
1148
+ socklen_t size;
1149
+ sctp_assoc_t assoc_id;
1150
+ struct sctp_status status;
1151
+ struct sctp_paddrinfo* spinfo;
1152
+ char tmpname[INET_ADDRSTRLEN];
1153
+
1154
+ bzero(&status, sizeof(status));
1155
+
1156
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
1157
+ assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
1158
+ size = sizeof(struct sctp_status);
1159
+
1160
+ if(sctp_opt_info(sock_fd, assoc_id, SCTP_STATUS, (void*)&status, &size) < 0)
1161
+ rb_raise(rb_eSystemCallError, "sctp_opt_info: %s", strerror(errno));
1162
+
1163
+ spinfo = &status.sstat_primary;
1164
+
1165
+ if (spinfo->spinfo_address.ss_family == AF_INET6) {
1166
+ struct sockaddr_in6 *sin6;
1167
+ sin6 = (struct sockaddr_in6 *)&spinfo->spinfo_address;
1168
+ inet_ntop(AF_INET6, &sin6->sin6_addr, tmpname, sizeof (tmpname));
1169
+ }
1170
+ else {
1171
+ struct sockaddr_in *sin;
1172
+ sin = (struct sockaddr_in *)&spinfo->spinfo_address;
1173
+ inet_ntop(AF_INET, &sin->sin_addr, tmpname, sizeof (tmpname));
1174
+ }
1175
+
1176
+ return rb_struct_new(v_sctp_status_struct,
1177
+ INT2NUM(status.sstat_assoc_id),
1178
+ INT2NUM(status.sstat_state),
1179
+ INT2NUM(status.sstat_rwnd),
1180
+ INT2NUM(status.sstat_unackdata),
1181
+ INT2NUM(status.sstat_penddata),
1182
+ INT2NUM(status.sstat_instrms),
1183
+ INT2NUM(status.sstat_outstrms),
1184
+ INT2NUM(status.sstat_fragmentation_point),
1185
+ rb_str_new2(tmpname)
1186
+ );
1187
+ }
1188
+
648
1189
  void Init_socket(){
649
1190
  mSCTP = rb_define_module("SCTP");
650
1191
  cSocket = rb_define_class_under(mSCTP, "Socket", rb_cObject);
651
1192
 
652
1193
  v_sndrcv_struct = rb_struct_define(
653
- "SndRecvInfo", "message", "stream", "flags",
654
- "ppid", "context", "ttl", "assoc_id", NULL
1194
+ "SendReceiveInfo", "message", "stream", "flags",
1195
+ "ppid", "context", "ttl", "association_id", "notification", "client", NULL
1196
+ );
1197
+
1198
+ v_assoc_change_struct = rb_struct_define(
1199
+ "AssocChange", "type", "length", "state", "error",
1200
+ "outbound_streams", "inbound_streams", "association_id", "info", NULL
1201
+ );
1202
+
1203
+ v_peeraddr_change_struct = rb_struct_define(
1204
+ "PeerAddrChange", "type", "length", "ip_address",
1205
+ "state", "error", "association_id", "info", NULL
1206
+ );
1207
+
1208
+ v_remote_error_struct = rb_struct_define(
1209
+ "RemoteError", "type", "length", "error", "association_id", "data", NULL
1210
+ );
1211
+
1212
+ v_send_failed_event_struct = rb_struct_define(
1213
+ "SendFailedEvent", "type", "length", "error", "association_id", "data", NULL
1214
+ );
1215
+
1216
+ v_shutdown_event_struct = rb_struct_define(
1217
+ "ShutdownEvent", "type", "length", "association_id", NULL
1218
+ );
1219
+
1220
+ v_sndinfo_struct = rb_struct_define(
1221
+ "SendInfo", "sid", "flags", "ppid", "context", "association_id", NULL
1222
+ );
1223
+
1224
+ v_adaptation_event_struct = rb_struct_define(
1225
+ "AdaptationEvent", "type", "length", "adaptation_indication", "association_id", NULL
1226
+ );
1227
+
1228
+ v_partial_delivery_event_struct = rb_struct_define(
1229
+ "PartialDeliveryEvent", "type", "length", "indication", "stream",
1230
+ "sequence_number", "association_id", NULL
1231
+ );
1232
+
1233
+ v_auth_event_struct = rb_struct_define(
1234
+ "AuthEvent", "type", "length", "key_number", "indication", "association_id", NULL
1235
+ );
1236
+
1237
+ v_sockaddr_in_struct = rb_struct_define(
1238
+ "SockAddrIn", "family", "port", "address", NULL
1239
+ );
1240
+
1241
+ v_sctp_status_struct = rb_struct_define(
1242
+ "Status", "association_id", "state", "receive_window", "unacknowledged_data",
1243
+ "pending_data", "inbound_streams", "outbound_streams", "fragmentation_point", "primary", NULL
1244
+ );
1245
+
1246
+ v_sctp_rtoinfo_struct = rb_struct_define(
1247
+ "RetransmissionInfo", "association_id", "initial", "max", "min", NULL
1248
+ );
1249
+
1250
+ v_sctp_associnfo_struct = rb_struct_define(
1251
+ "AssociationInfo", "association_id", "max_retransmission_count",
1252
+ "number_peer_destinations", "peer_receive_window", "local_receive_window",
1253
+ "cookie_life", NULL
1254
+ );
1255
+
1256
+ v_sctp_default_send_params_struct = rb_struct_define(
1257
+ "DefaultSendParams", "stream", "ssn", "flags", "ppid", "context",
1258
+ "ttl", "tsn", "cumtsn", "association_id", NULL
655
1259
  );
656
1260
 
657
1261
  rb_define_method(cSocket, "initialize", rsctp_init, -1);
@@ -661,11 +1265,22 @@ void Init_socket(){
661
1265
  rb_define_method(cSocket, "connect", rsctp_connect, -1);
662
1266
  rb_define_method(cSocket, "getpeernames", rsctp_getpeernames, 0);
663
1267
  rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames, 0);
1268
+ rb_define_method(cSocket, "get_status", rsctp_get_status, 0);
1269
+ rb_define_method(cSocket, "get_default_send_params", rsctp_get_default_send_params, 0);
1270
+ rb_define_method(cSocket, "get_retransmission_info", rsctp_get_retransmission_info, 0);
1271
+ rb_define_method(cSocket, "get_association_info", rsctp_get_association_info, 0);
664
1272
  rb_define_method(cSocket, "listen", rsctp_listen, -1);
665
1273
  rb_define_method(cSocket, "peeloff!", rsctp_peeloff, 1);
666
1274
  rb_define_method(cSocket, "recvmsg", rsctp_recvmsg, -1);
1275
+ rb_define_method(cSocket, "send", rsctp_send, 1);
1276
+
1277
+ #ifdef HAVE_SCTP_SENDV
1278
+ rb_define_method(cSocket, "sendv", rsctp_sendv, 1);
1279
+ #endif
1280
+
667
1281
  rb_define_method(cSocket, "sendmsg", rsctp_sendmsg, 1);
668
1282
  rb_define_method(cSocket, "set_initmsg", rsctp_set_initmsg, 1);
1283
+ rb_define_method(cSocket, "shutdown", rsctp_shutdown, -1);
669
1284
  rb_define_method(cSocket, "subscribe", rsctp_subscribe, 1);
670
1285
 
671
1286
  rb_define_attr(cSocket, "domain", 1, 1);
@@ -674,6 +1289,37 @@ void Init_socket(){
674
1289
  rb_define_attr(cSocket, "association_id", 1, 1);
675
1290
  rb_define_attr(cSocket, "port", 1, 1);
676
1291
 
677
- /* 0.0.1: The version of this library */
678
- rb_define_const(cSocket, "VERSION", rb_str_new2("0.0.1"));
1292
+ /* 0.0.5: The version of this library */
1293
+ rb_define_const(cSocket, "VERSION", rb_str_new2("0.0.5"));
1294
+
1295
+ /* send flags */
1296
+
1297
+ /* Message is unordered */
1298
+ rb_define_const(cSocket, "SCTP_UNORDERED", INT2NUM(SCTP_UNORDERED));
1299
+
1300
+ /* Override the primary address */
1301
+ rb_define_const(cSocket, "SCTP_ADDR_OVER", INT2NUM(SCTP_ADDR_OVER));
1302
+
1303
+ /* Send an ABORT to peer */
1304
+ rb_define_const(cSocket, "SCTP_ABORT", INT2NUM(SCTP_ABORT));
1305
+
1306
+ /* Start a shutdown procedure */
1307
+ rb_define_const(cSocket, "SCTP_EOF", INT2NUM(SCTP_EOF));
1308
+
1309
+ /* Send to all associations */
1310
+ rb_define_const(cSocket, "SCTP_SENDALL", INT2NUM(SCTP_SENDALL));
1311
+
1312
+ rb_define_const(cSocket, "MSG_NOTIFICATION", INT2NUM(MSG_NOTIFICATION));
1313
+
1314
+ // ASSOCIATION STATES //
1315
+
1316
+ rb_define_const(cSocket, "SCTP_EMPTY", INT2NUM(SCTP_EMPTY));
1317
+ rb_define_const(cSocket, "SCTP_CLOSED", INT2NUM(SCTP_CLOSED));
1318
+ rb_define_const(cSocket, "SCTP_COOKIE_WAIT", INT2NUM(SCTP_COOKIE_WAIT));
1319
+ rb_define_const(cSocket, "SCTP_COOKIE_ECHOED", INT2NUM(SCTP_COOKIE_ECHOED));
1320
+ rb_define_const(cSocket, "SCTP_ESTABLISHED", INT2NUM(SCTP_ESTABLISHED));
1321
+ rb_define_const(cSocket, "SCTP_SHUTDOWN_PENDING", INT2NUM(SCTP_SHUTDOWN_PENDING));
1322
+ rb_define_const(cSocket, "SCTP_SHUTDOWN_SENT", INT2NUM(SCTP_SHUTDOWN_SENT));
1323
+ rb_define_const(cSocket, "SCTP_SHUTDOWN_RECEIVED", INT2NUM(SCTP_SHUTDOWN_RECEIVED));
1324
+ rb_define_const(cSocket, "SCTP_SHUTDOWN_ACK_SENT", INT2NUM(SCTP_SHUTDOWN_ACK_SENT));
679
1325
  }
data/sctp-socket.gemspec CHANGED
@@ -1,11 +1,10 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'sctp-socket'
3
- spec.version = '0.0.1'
3
+ spec.version = '0.0.5'
4
4
  spec.author = 'Daniel Berger'
5
5
  spec.email = 'djberg96@gmail.com'
6
6
  spec.summary = 'Ruby bindings for SCTP sockets'
7
- spec.description = 'Ruby bindings for SCTP sockets'
8
- spec.homepage = 'https://github.com/djberg96/sctp-sockets'
7
+ spec.homepage = 'https://github.com/djberg96/sctp-socket'
9
8
  spec.license = 'Apache-2.0'
10
9
  spec.cert_chain = ['certs/djberg96_pub.pem']
11
10
 
@@ -15,8 +14,14 @@ Gem::Specification.new do |spec|
15
14
 
16
15
  spec.extensions = ['ext/sctp/extconf.rb']
17
16
 
18
- spec.add_development_dependency 'bundler'
19
- spec.add_development_dependency 'rake'
20
- spec.add_development_dependency 'rake-compiler'
21
- spec.add_development_dependency 'rspec'
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'
21
+
22
+ spec.description = <<-EOF
23
+ The sctp-socket library provides Ruby bindings for SCTP sockets. is a
24
+ message oriented, reliable transport protocol with direct support for
25
+ multihoming.
26
+ EOF
22
27
  end
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.1
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Berger
@@ -35,65 +35,68 @@ cert_chain:
35
35
  ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
36
36
  WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
37
37
  -----END CERTIFICATE-----
38
- date: 2020-11-24 00:00:00.000000000 Z
38
+ date: 2021-12-15 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: '0'
46
+ version: '2.1'
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: '0'
53
+ version: '2.1'
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: '0'
60
+ version: '13.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: '0'
67
+ version: '13.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: '0'
74
+ version: '1.1'
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: '0'
81
+ version: '1.1'
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: '0'
88
+ version: '3.9'
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: '0'
96
- description: Ruby bindings for SCTP sockets
95
+ version: '3.9'
96
+ description: |2
97
+ The sctp-socket library provides Ruby bindings for SCTP sockets. is a
98
+ message oriented, reliable transport protocol with direct support for
99
+ multihoming.
97
100
  email: djberg96@gmail.com
98
101
  executables: []
99
102
  extensions:
@@ -116,7 +119,7 @@ files:
116
119
  - ext/sctp/socket/client.c
117
120
  - ext/sctp/socket/server.c
118
121
  - sctp-socket.gemspec
119
- homepage: https://github.com/djberg96/sctp-sockets
122
+ homepage: https://github.com/djberg96/sctp-socket
120
123
  licenses:
121
124
  - Apache-2.0
122
125
  metadata: {}
@@ -135,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
138
  - !ruby/object:Gem::Version
136
139
  version: '0'
137
140
  requirements: []
138
- rubygems_version: 3.0.6
141
+ rubygems_version: 3.2.25
139
142
  signing_key:
140
143
  specification_version: 4
141
144
  summary: Ruby bindings for SCTP sockets
metadata.gz.sig CHANGED
Binary file