sparoid 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +6 -6
- data/.github/workflows/release.yml +20 -0
- data/CHANGELOG.md +12 -0
- data/README.md +9 -1
- data/lib/sparoid/version.rb +1 -1
- data/lib/sparoid.rb +23 -12
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d077c30ec18d566719f9d594991798d8ecd94ac74938d5f5b21fb37a677066ca
|
|
4
|
+
data.tar.gz: b5f44ce465c4705dfdf5a0c705ad29603744be2145a831cd9c000be0ebb03ea0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e937c061cacbadf3206cffc1d96eb4f99dd667ce8daf1becb91db2eba8aa3893384dd31a59924acc255c11e39bd0aad3ebed7b5e29430c92356e3c54162d2d1b
|
|
7
|
+
data.tar.gz: 5ee4e40eef7d12ee5e052ca92452bdae45814f81260d10e35339710255eec8b8cd207fcba2cd31af73a35b50344a2d224cb5f237ce8c6a498b94b7c61249b61e
|
data/.github/workflows/main.yml
CHANGED
|
@@ -14,9 +14,9 @@ jobs:
|
|
|
14
14
|
ruby: [ 3.2, 3.3, 3.4, 4.0, ruby-head ]
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
steps:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
- uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: ${{ matrix.ruby }}
|
|
21
|
+
bundler-cache: true
|
|
22
|
+
- run: bundle exec rake
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
|
+
- uses: ruby/setup-ruby@v1
|
|
17
|
+
with:
|
|
18
|
+
ruby-version: '3.4'
|
|
19
|
+
bundler-cache: true
|
|
20
|
+
- uses: rubygems/release-gem@v1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [2.2.0] - 2026-05-06
|
|
2
|
+
|
|
3
|
+
- Raise when sendmsg fails for every resolved address (#23)
|
|
4
|
+
|
|
5
|
+
## [2.1.2] - 2026-04-30
|
|
6
|
+
|
|
7
|
+
- Skip addresses that fail synchronous connect in fdpass (#20)
|
|
8
|
+
|
|
9
|
+
## [2.1.1] - 2026-04-13
|
|
10
|
+
|
|
11
|
+
- Remove the usage of Timeout (#19)
|
|
12
|
+
|
|
1
13
|
## [2.1.0] - 2026-03-10
|
|
2
14
|
|
|
3
15
|
- Aligning CLI with Crystal client interface (`send`/`connect` subcommands with flags)
|
data/README.md
CHANGED
|
@@ -34,7 +34,15 @@ Host *.example.com
|
|
|
34
34
|
|
|
35
35
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
36
36
|
|
|
37
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
37
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
38
|
+
|
|
39
|
+
To release a new version:
|
|
40
|
+
|
|
41
|
+
1. Bump `Sparoid::VERSION` in `lib/sparoid/version.rb` and add an entry to `CHANGELOG.md`.
|
|
42
|
+
2. Open a PR with the bump, get it merged into `main`.
|
|
43
|
+
3. Push a tag matching the new version, e.g. `git tag v2.1.2 && git push origin v2.1.2`.
|
|
44
|
+
|
|
45
|
+
The `Release` GitHub Actions workflow then builds the gem and publishes it to [rubygems.org](https://rubygems.org) via OIDC trusted publishing — no API key required.
|
|
38
46
|
|
|
39
47
|
## Contributing
|
|
40
48
|
|
data/lib/sparoid/version.rb
CHANGED
data/lib/sparoid.rb
CHANGED
|
@@ -22,20 +22,27 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
|
|
|
22
22
|
# Send an authorization packet
|
|
23
23
|
def auth(key, hmac_key, host, port, open_for_ip: nil)
|
|
24
24
|
addrs = resolve_ip_addresses(host, port)
|
|
25
|
-
|
|
25
|
+
errors = []
|
|
26
|
+
successful_addrs = addrs.filter_map do |addr|
|
|
26
27
|
messages = generate_messages(open_for_ip)
|
|
27
28
|
data = messages.map do |message|
|
|
28
29
|
prefix_hmac(hmac_key, encrypt(key, message))
|
|
29
30
|
end
|
|
30
31
|
sendmsg(addr, data)
|
|
32
|
+
addr
|
|
33
|
+
rescue SystemCallError => e
|
|
34
|
+
errors << "#{addr.ip_address}: #{e.message}"
|
|
35
|
+
nil
|
|
31
36
|
end
|
|
32
37
|
|
|
38
|
+
raise Error, "Sparoid failed to send to any address for #{host}: #{errors.join("; ")}" if successful_addrs.empty?
|
|
39
|
+
|
|
33
40
|
# wait some time for the server to actually open the port
|
|
34
41
|
# if we don't wait the next SYN package will be dropped
|
|
35
42
|
# and it have to be redelivered, adding 1 second delay
|
|
36
43
|
sleep 0.02
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
successful_addrs
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
# Generate new aes and hmac keys, print to stdout
|
|
@@ -48,12 +55,18 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
|
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
# Connect to a TCP server and pass the FD to the parent
|
|
51
|
-
def fdpass(addrs, port, connect_timeout: 10) # rubocop:disable Metrics/AbcSize
|
|
52
|
-
# try connect to all IPs
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
def fdpass(addrs, port, connect_timeout: 10) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
59
|
+
# try connect to all IPs; skip addrs that fail synchronously (e.g. no route)
|
|
60
|
+
viable_addrs = []
|
|
61
|
+
sockets = addrs.filter_map do |addr|
|
|
62
|
+
s = Socket.new(addr.afamily, Socket::SOCK_STREAM)
|
|
63
|
+
s.connect_nonblock(Socket.sockaddr_in(port, addr.ip_address), exception: false)
|
|
64
|
+
viable_addrs << addr
|
|
65
|
+
s
|
|
66
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNREFUSED => e
|
|
67
|
+
warn "Sparoid: skip #{addr.ip_address}: #{e.message}"
|
|
68
|
+
s&.close
|
|
69
|
+
nil
|
|
57
70
|
end
|
|
58
71
|
# wait for any socket to be connected
|
|
59
72
|
until sockets.empty?
|
|
@@ -62,7 +75,7 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
|
|
|
62
75
|
writeable.each do |s|
|
|
63
76
|
idx = sockets.index(s)
|
|
64
77
|
sockets.delete_at(idx) # don't retry this socket again
|
|
65
|
-
addr =
|
|
78
|
+
addr = viable_addrs.delete_at(idx) # find the IP for the socket
|
|
66
79
|
begin
|
|
67
80
|
s.connect_nonblock(Socket.sockaddr_in(port, addr.ip_address)) # check for errors
|
|
68
81
|
rescue Errno::EISCONN
|
|
@@ -99,11 +112,9 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
|
|
|
99
112
|
socket.nonblock = false
|
|
100
113
|
data.each do |packet|
|
|
101
114
|
socket.sendmsg packet, 0, addr
|
|
102
|
-
rescue StandardError => e
|
|
103
|
-
warn "Sparoid error: #{e.message}"
|
|
104
115
|
end
|
|
105
116
|
ensure
|
|
106
|
-
socket
|
|
117
|
+
socket&.close
|
|
107
118
|
end
|
|
108
119
|
|
|
109
120
|
def encrypt(key, data)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sparoid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carl Hörberg
|
|
@@ -17,6 +17,7 @@ extensions: []
|
|
|
17
17
|
extra_rdoc_files: []
|
|
18
18
|
files:
|
|
19
19
|
- ".github/workflows/main.yml"
|
|
20
|
+
- ".github/workflows/release.yml"
|
|
20
21
|
- ".gitignore"
|
|
21
22
|
- ".rubocop.yml"
|
|
22
23
|
- CHANGELOG.md
|