sctp-socket 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89d20d26ad8e90c5673d4d126da8daa8f69d907a54ba0ddc9caf529ef5929c6e
4
- data.tar.gz: 886d28171c2e7242a7875b7a998e7073a9bec469da7da5b9205859a4e2d3e257
3
+ metadata.gz: 81048dca4080fa86d9a50626a8fe69462af57e7d95231083e03272757949cddc
4
+ data.tar.gz: c4f7e5952deeefbb1b7a453179241bb79d6256f90c3b4ede166a3f99897f2def
5
5
  SHA512:
6
- metadata.gz: ee23fbff8da2e3efa66f87f583ba1f631d39957a6f74bff530d1b71ae1a15ab773ecb6653f34d8d5e17e034a15f6a736c90a16f3c8f3ed636734ab674dee54ca
7
- data.tar.gz: 68ff54d9088bfe723f0726c3bcc41c102aab7c3f631f1156f64651bd078ffa1a852b247505a4babf36cb37c61aa11726587db407ad34171c974b6afca96283a8
6
+ metadata.gz: '001209834d222cab4fe021741e9cfa91448c7fae70ca9418de8e3b05084d2a30fe5897b57adb42394525efc7dfef58cf8d8ca08e6218d7a2b490e7172d1a2454'
7
+ data.tar.gz: 9a597dcd249ef7133a0bbd8fa145a018e41c5bcc76a3fcfaf8b658d90f40b39afbb585dbb3c05fc4a4173b42d495814f7a8ba1934a7c8fb7baf0a3c3d1b69ca9
checksums.yaml.gz.sig CHANGED
Binary file
@@ -35,3 +35,25 @@ jobs:
35
35
  bundler-cache: true
36
36
  - name: Run Specs
37
37
  run: bundle exec rake
38
+ freebsd:
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - name: Test in FreeBSD
43
+ id: test
44
+ uses: vmactions/freebsd-vm@v1
45
+ with:
46
+ usesh: true
47
+ prepare: |
48
+ pkg install -y llvm ruby devel/ruby-gems sctplib git-tiny
49
+
50
+ run: |
51
+ git config --global --add safe.directory /home/runner/work/sctp-socket/sctp-socket
52
+ kldload sctp
53
+ ifconfig lo1 create
54
+ ifconfig lo1 1.1.1.1/24 up
55
+ ifconfig lo2 create
56
+ ifconfig lo2 1.1.1.2/24 up
57
+ gem install bundler --no-document
58
+ bundle install --quiet
59
+ bundle exec rake
data/CHANGES.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.1.3 - 22-Jan-2025
2
+ * The close method now accepts an optional `linger` argument.
3
+ * The bindx method now accepts an optional `reuse_addr` argument.
4
+ * Fixed a bug in the bindx method for address arrays with a single element.
5
+
1
6
  ## 0.1.2 - 10-Jan-2025
2
7
  * Added support for BSD.
3
8
 
data/README.md CHANGED
@@ -67,7 +67,7 @@ Currently this has only been developed and tested on Linux and BSD. Other
67
67
  platforms will probably only be supported via community contributions.
68
68
 
69
69
  The sendv and recvv methods may not be available. Use the sendmsg and recvmsg
70
- methods instead.
70
+ methods instead if that's the case.
71
71
 
72
72
  I am currently unable to subclass the Socket class from Ruby's standard library.
73
73
  For whatever reason the call to rb_call_super works, but the fileno is always
data/Rakefile CHANGED
@@ -39,13 +39,21 @@ end
39
39
 
40
40
  desc "Create dummy IP addresses to use for testing"
41
41
  task :create_dummy_links do
42
- system('sudo ip link add dummy1 type dummy')
43
- system('sudo ip link add dummy2 type dummy')
44
- system('sudo ip addr add 1.1.1.1/24 dev dummy1')
45
- system('sudo ip addr add 1.1.1.2/24 dev dummy2')
46
- system('sudo ip link set dummy1 up')
47
- system('sudo ip link set dummy2 up')
48
- system('ip link show')
42
+ if RbConfig::CONFIG['host_os'] =~ /linux/i
43
+ system('sudo ip link add dummy1 type dummy')
44
+ system('sudo ip link add dummy2 type dummy')
45
+ system('sudo ip addr add 1.1.1.1/24 dev dummy1')
46
+ system('sudo ip addr add 1.1.1.2/24 dev dummy2')
47
+ system('sudo ip link set dummy1 up')
48
+ system('sudo ip link set dummy2 up')
49
+ system('ip link show')
50
+ else
51
+ system("sudo ifconfig lo1 create")
52
+ system("sudo ifconfig lo1 1.1.1.1/24 up")
53
+ system("sudo ifconfig lo2 create")
54
+ system("sudo ifconfig lo2 1.1.1.2/24 up")
55
+ system("sudo ifconfig -a")
56
+ end
49
57
  end
50
58
 
51
59
  RSpec::Core::RakeTask.new
@@ -10,7 +10,7 @@ begin
10
10
  socket = SCTP::Socket.new
11
11
 
12
12
  # Optional, but could bind to a subset of available addresses
13
- p socket.bindx(:addresses => addresses)
13
+ # p socket.bindx(:addresses => addresses)
14
14
 
15
15
  # Initial connection
16
16
  p socket.connectx(:addresses => addresses, :port => port)
@@ -30,6 +30,7 @@ begin
30
30
 
31
31
  while true
32
32
  info = socket.recvmsg
33
+ # info = socket.recvv # Or this
33
34
  p info
34
35
  end
35
36
  ensure
data/ext/sctp/socket.c CHANGED
@@ -335,11 +335,28 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
335
335
  *
336
336
  * Bind a subset of IP addresses associated with the host system on the
337
337
  * given port, or a port assigned by the operating system if none is provided.
338
+ * You may bind a maximum of eight IP addresses.
338
339
  *
339
340
  * Note that you can both add or remove an address to or from the socket
340
341
  * using the SCTP_BINDX_ADD_ADDR (default) or SCTP_BINDX_REM_ADDR constants,
341
342
  * respectively.
342
343
  *
344
+ * Possible options:
345
+ *
346
+ * * addresses - Array of IP addresses to bind to. If none are specified then
347
+ * INADDR_ANY is used.
348
+ *
349
+ * * port - The port to bind to. If none is specified then 0 is used, i.e. the
350
+ * OS will select one for you.
351
+ *
352
+ * * flags - Flags to pass to the underlying sctp_bindx function. In practice
353
+ * there are only two options: BINDX_ADD_ADDR and BINDX_REM_ADDR. By
354
+ * default a flag of BINDX_ADD_ADDR is assumed.
355
+ *
356
+ * * reuse_addr - If set to true, then the SO_REUSEADDR flag will be applied to
357
+ * the socket before the bind call. This will allow other sockets to reuse
358
+ * the addresses that are currently bound to the socket.
359
+ *
343
360
  * Example:
344
361
  *
345
362
  * socket = SCTP::Socket.new
@@ -357,8 +374,8 @@ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
357
374
  */
358
375
  static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
359
376
  struct sockaddr_in addrs[8];
360
- int i, fileno, num_ip, flags, domain, port;
361
- VALUE v_addresses, v_port, v_flags, v_address, v_options;
377
+ int i, fileno, num_ip, flags, domain, port, on;
378
+ VALUE v_addresses, v_port, v_flags, v_address, v_reuse_addr, v_options;
362
379
 
363
380
  rb_scan_args(argc, argv, "01", &v_options);
364
381
 
@@ -370,6 +387,7 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
370
387
  v_addresses = rb_hash_aref2(v_options, "addresses");
371
388
  v_flags = rb_hash_aref2(v_options, "flags");
372
389
  v_port = rb_hash_aref2(v_options, "port");
390
+ v_reuse_addr = rb_hash_aref2(v_options, "reuse_addr");
373
391
 
374
392
  if(NIL_P(v_port))
375
393
  port = 0;
@@ -386,10 +404,13 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
386
404
  else
387
405
  num_ip = (int)RARRAY_LEN(v_addresses);
388
406
 
407
+ if(num_ip > 8)
408
+ rb_raise(rb_eArgError, "too many IP addresses to bind, maximum is eight");
409
+
389
410
  domain = NUM2INT(rb_iv_get(self, "@domain"));
390
411
  fileno = NUM2INT(rb_iv_get(self, "@fileno"));
391
412
 
392
- if(num_ip > 1){
413
+ if(!NIL_P(v_addresses)){
393
414
  for(i = 0; i < num_ip; i++){
394
415
  v_address = RARRAY_PTR(v_addresses)[i];
395
416
  addrs[i].sin_family = domain;
@@ -409,6 +430,12 @@ static VALUE rsctp_bindx(int argc, VALUE* argv, VALUE self){
409
430
  #endif
410
431
  }
411
432
 
433
+ if(v_reuse_addr == Qtrue){
434
+ on = 1;
435
+ if(setsockopt(fileno, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
436
+ rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
437
+ }
438
+
412
439
  if(sctp_bindx(fileno, (struct sockaddr *) addrs, num_ip, flags) != 0)
413
440
  rb_raise(rb_eSystemCallError, "sctp_bindx: %s", strerror(errno));
414
441
 
@@ -497,15 +524,46 @@ static VALUE rsctp_connectx(int argc, VALUE* argv, VALUE self){
497
524
  *
498
525
  * Close the socket. You should always do this.
499
526
  *
527
+ * By default the underlying close operation is non-blocking. This means that the
528
+ * bound IP addresses may not be available right away after closing. You may
529
+ * optionally control this behavior with the +linger+ option.
530
+ *
531
+ *
532
+ * * linger - If present, this should be set to a numeric value, in seconds.
533
+ * The value will cause the close operation to block for that number of
534
+ * seconds, after which it will return (i.e. return to non-blocking).
535
+ *
500
536
  * Example:
501
537
  *
502
538
  * socket = SCTP::Socket.new
503
- * socket.close
539
+ * socket.close # or
540
+ * socket.close(linger: 5)
504
541
  */
505
- static VALUE rsctp_close(VALUE self){
506
- VALUE v_fileno = rb_iv_get(self, "@fileno");
542
+ static VALUE rsctp_close(int argc, VALUE* argv, VALUE self){
543
+ VALUE v_options, v_linger;
544
+ int fileno;
545
+
546
+ rb_scan_args(argc, argv, "01", &v_options);
547
+
548
+ if(NIL_P(v_options))
549
+ v_options = rb_hash_new();
550
+
551
+ Check_Type(v_options, T_HASH);
552
+
553
+ v_linger = rb_hash_aref2(v_options, "linger");
554
+
555
+ fileno = NUM2INT(rb_iv_get(self, "@fileno"));
556
+
557
+ if(!NIL_P(v_linger)){
558
+ struct linger lin;
559
+ lin.l_onoff = 1;
560
+ lin.l_linger = NUM2INT(v_linger);
561
+
562
+ if(setsockopt(fileno, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0)
563
+ rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
564
+ }
507
565
 
508
- if(close(NUM2INT(v_fileno)))
566
+ if(close(fileno))
509
567
  rb_raise(rb_eSystemCallError, "close: %s", strerror(errno));
510
568
 
511
569
  return self;
@@ -695,6 +753,7 @@ static VALUE rsctp_sendv(VALUE self, VALUE v_options){
695
753
  rb_raise(rb_eArgError, "Array size is greater than IOV_MAX");
696
754
 
697
755
  // TODO: Make this configurable
756
+ spa.sendv_flags = SCTP_SEND_SNDINFO_VALID;
698
757
  spa.sendv_sndinfo.snd_flags = SCTP_UNORDERED;
699
758
  spa.sendv_sndinfo.snd_assoc_id = NUM2INT(rb_iv_get(self, "@association_id"));
700
759
 
@@ -2298,7 +2357,7 @@ void Init_socket(void){
2298
2357
 
2299
2358
  rb_define_method(cSocket, "autoclose=", rsctp_set_autoclose, 1);
2300
2359
  rb_define_method(cSocket, "bindx", rsctp_bindx, -1);
2301
- rb_define_method(cSocket, "close", rsctp_close, 0);
2360
+ rb_define_method(cSocket, "close", rsctp_close, -1);
2302
2361
  rb_define_method(cSocket, "connectx", rsctp_connectx, -1);
2303
2362
  rb_define_method(cSocket, "delete_shared_key", rsctp_delete_shared_key, -1);
2304
2363
  rb_define_method(cSocket, "disable_fragments=", rsctp_disable_fragments, 1);
@@ -2344,8 +2403,8 @@ void Init_socket(void){
2344
2403
  rb_define_attr(cSocket, "association_id", 1, 1);
2345
2404
  rb_define_attr(cSocket, "port", 1, 1);
2346
2405
 
2347
- /* 0.1.2: The version of this library */
2348
- rb_define_const(cSocket, "VERSION", rb_str_new2("0.1.2"));
2406
+ /* 0.1.3: The version of this library */
2407
+ rb_define_const(cSocket, "VERSION", rb_str_new2("0.1.3"));
2349
2408
 
2350
2409
  /* send flags */
2351
2410
 
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.1.2'
3
+ spec.version = '0.1.3'
4
4
  spec.author = 'Daniel Berger'
5
5
  spec.email = 'djberg96@gmail.com'
6
6
  spec.summary = 'Ruby bindings for SCTP sockets'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sctp-socket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Berger
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - |
@@ -35,7 +35,7 @@ cert_chain:
35
35
  ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
36
36
  WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
37
37
  -----END CERTIFICATE-----
38
- date: 2025-01-10 00:00:00.000000000 Z
38
+ date: 2025-01-22 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: bundler
@@ -133,7 +133,7 @@ metadata:
133
133
  wiki_uri: https://github.com/djberg96/sctp-socket/wiki
134
134
  rubygems_mfa_required: 'true'
135
135
  funding_uri: https://github.com/sponsors/djberg96
136
- post_install_message:
136
+ post_install_message:
137
137
  rdoc_options: []
138
138
  require_paths:
139
139
  - lib
@@ -149,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  version: '0'
150
150
  requirements: []
151
151
  rubygems_version: 3.5.22
152
- signing_key:
152
+ signing_key:
153
153
  specification_version: 4
154
154
  summary: Ruby bindings for SCTP sockets
155
155
  test_files: []
metadata.gz.sig CHANGED
Binary file