protocol-zmtp 0.10.3 → 0.10.4
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/CHANGELOG.md +297 -0
- data/README.md +12 -12
- data/lib/protocol/zmtp/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea36d2dec54002414471143e5dcffcbc6fcedb10a53a52f9c22684e5657c4a0d
|
|
4
|
+
data.tar.gz: 17e2377d7534476344dd47164d8b6fde121526b4d2715af4dfb5c4682bd98bf8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8ecaa0325141c8e1e41f8389aa1b431328b2c9b0c83c912f301119bd49503a001889aec9db285485fe786022033927588e3843dd8af60dfb1597619ca57aff40
|
|
7
|
+
data.tar.gz: 67af1e45d9834d9ae7ed47352758eca7b92817691bf80518addfb66de28979d4a0bbaf2ec53ff802c8fbefd788a88bfeb6d794b9669cda1fdc57be20af00f669
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.10.4 - 2026-07-23
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Release source is now the `zeromq/omq.rb` monorepo.
|
|
10
|
+
|
|
11
|
+
## 0.10.3 — 2026-05-30
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **CURVE: COMMAND flag in encrypted inner byte must be 0x02, not 0x04.**
|
|
16
|
+
CurveZMQ's inner plaintext flags byte uses a compact layout where
|
|
17
|
+
bit 1 (0x02) means COMMAND, but encrypt/decrypt used the wire-level
|
|
18
|
+
COMMAND bit (0x04). This broke interop with libzmq: a CURVE-encrypted
|
|
19
|
+
SUBSCRIBE from a libzmq SUB was treated as data and silently dropped,
|
|
20
|
+
so the PUB never registered the subscription.
|
|
21
|
+
|
|
22
|
+
## 0.10.2 — 2026-05-28
|
|
23
|
+
|
|
24
|
+
- Bump version (was missed in 0.10.1).
|
|
25
|
+
|
|
26
|
+
## 0.10.1 — 2026-05-28
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`Connection#write_wire_batch`** writes multiple pre-encoded wire
|
|
31
|
+
byte strings under a single mutex acquisition, amortizing lock
|
|
32
|
+
overhead for fan-out send pumps.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **Single-write short frames.** Frames with bodies <= 255 bytes now
|
|
37
|
+
combine the 2-byte header and body into one `@io.write` call,
|
|
38
|
+
halving per-frame io-stream mutex overhead (+5-7% small-message
|
|
39
|
+
TCP throughput).
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **NULL mechanism greeting: `as-server` field is now always 0.**
|
|
44
|
+
RFC 23 requires `as-server = 0` for the NULL mechanism, but the
|
|
45
|
+
server side was forwarding the caller's flag (`0x01`). This broke
|
|
46
|
+
interoperability with strict ZMTP 3.x peers that validate the field.
|
|
47
|
+
|
|
48
|
+
## 0.10.0 — 2026-04-20
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **`PeerInfo` extended with `identity`.** `PeerInfo = Data.define(:public_key, :identity)`
|
|
53
|
+
now bundles both post-handshake peer anchors. CURVE authenticators
|
|
54
|
+
still receive a `PeerInfo` during auth (with `identity: ""`, since
|
|
55
|
+
identity arrives post-auth).
|
|
56
|
+
- **`Connection#peer_info`.** After a successful handshake, returns a
|
|
57
|
+
frozen `PeerInfo` combining the peer's CURVE public key (if any) and
|
|
58
|
+
`ZMQ_IDENTITY`. Usable directly as a Hash key. Nil before handshake.
|
|
59
|
+
Upper layers (e.g. omq-qos levels 2/3) use the whole value as a
|
|
60
|
+
stable per-peer identifier across reconnects.
|
|
61
|
+
- **Mechanism return hashes carry `peer_public_key`.** Both
|
|
62
|
+
`Mechanism::Null#handshake!` and `Mechanism::Curve` handshake paths now
|
|
63
|
+
return `peer_public_key:` alongside `peer_identity:` etc. (nil for
|
|
64
|
+
NULL; the peer's long-term `crypto::PublicKey` for CURVE).
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **Drop hot-path binary-encoding coercion and frame-body freezes.**
|
|
69
|
+
`Frame#initialize` and `Frame.encode_message` no longer copy non-binary
|
|
70
|
+
bodies via `String#b` — callers (OMQ's `Writable#send`, ZMTP command
|
|
71
|
+
builders) already hand in binary bytes, and for an outgoing message the
|
|
72
|
+
receiver (`String.new(capacity:) << body`) treats any encoding as raw
|
|
73
|
+
bytes once the buffer itself is binary. `Connection#receive_message`
|
|
74
|
+
also stops freezing each frame body and the returned parts array; the
|
|
75
|
+
caller decides what to freeze. Net effect: fewer allocations per
|
|
76
|
+
message and no per-part `.freeze` on the receive path.
|
|
77
|
+
|
|
78
|
+
## 0.9.0 — 2026-04-18
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **`Frame.read_from` uses `io.peek` to collapse the long-frame read
|
|
83
|
+
path.** The previous implementation issued 2 `read_exactly` calls for
|
|
84
|
+
short frames (header + body) and 3 for long frames (2-byte header,
|
|
85
|
+
remaining 7 size bytes, body). It now peeks just enough header bytes
|
|
86
|
+
(2 for short, 9 for long), decodes the size from the peek buffer, and
|
|
87
|
+
drains header + body in a single `read_exactly(header_size + size)`.
|
|
88
|
+
Long frames drop to the same 2-call read path as short frames; the
|
|
89
|
+
`read_long_size` helper is gone. A speculative `read_exactly(9)` would
|
|
90
|
+
not be safe here — a <7-byte short frame at idle would hang waiting
|
|
91
|
+
for bytes that never arrive, or steal bytes from the next frame on a
|
|
92
|
+
mixed stream.
|
|
93
|
+
|
|
94
|
+
- **Transport IO must now also respond to `#peek`** in addition to
|
|
95
|
+
`#read_exactly`, `#write`, `#flush`, and `#close`. `io-stream`'s
|
|
96
|
+
`Async::IO::Stream` already provides this; custom transport wrappers
|
|
97
|
+
need a `#peek(&block)` that yields the current read buffer and fills
|
|
98
|
+
it until the block returns truthy.
|
|
99
|
+
|
|
100
|
+
## 0.8.1 — 2026-04-16
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
|
|
104
|
+
- **`Frame#initialize` skips redundant `.b` copy.** Body is now kept
|
|
105
|
+
as-is when it is already `Encoding::BINARY`, avoiding a per-frame
|
|
106
|
+
String allocation on the read path (`read_exactly` and `byteslice`
|
|
107
|
+
already return binary strings).
|
|
108
|
+
|
|
109
|
+
- **`Frame#to_wire` uses `String.new(capacity:)` with `<<` appends**
|
|
110
|
+
instead of `+` concatenation, reducing from 3 intermediate String
|
|
111
|
+
allocations per frame to 1 pre-sized buffer.
|
|
112
|
+
|
|
113
|
+
- **`Frame.encode_message` pre-computes wire size** for the output
|
|
114
|
+
buffer `capacity:` hint, avoiding re-allocations during fan-out.
|
|
115
|
+
Single-part messages (the common case) skip the iteration and
|
|
116
|
+
inline the size calculation.
|
|
117
|
+
|
|
118
|
+
- **`Command.ping` / `.pong` default to `EMPTY_BINARY`** instead of
|
|
119
|
+
`"".b`, which allocated a mutable copy on every call despite
|
|
120
|
+
`frozen_string_literal: true`. `#ping_ttl_and_context` uses
|
|
121
|
+
`EMPTY_BINARY` for the empty-context fallback.
|
|
122
|
+
|
|
123
|
+
- **`Subscription.body` drops redundant outer `.b`** — both operands
|
|
124
|
+
are already binary, so the concatenation result is binary without
|
|
125
|
+
a second encoding conversion.
|
|
126
|
+
|
|
127
|
+
## 0.8.0 — 2026-04-15
|
|
128
|
+
|
|
129
|
+
### Added
|
|
130
|
+
|
|
131
|
+
- **`Codec::Subscription`** — helper module that unifies ZMTP 3.0
|
|
132
|
+
message-form (`\x01`/`\x00` + prefix data frame) and ZMTP 3.1
|
|
133
|
+
command-form (`SUBSCRIBE`/`CANCEL` command frame) subscription
|
|
134
|
+
encodings. `.body(prefix, cancel:)` builds the message-form body;
|
|
135
|
+
`.parse(frame)` returns `[:subscribe|:cancel, prefix]` for either
|
|
136
|
+
form, letting upper layers accept both without branching.
|
|
137
|
+
- **`Connection#peer_major` / `#peer_minor`** — ZMTP wire revision of
|
|
138
|
+
the peer, captured from the greeting. Lets upper layers pick the
|
|
139
|
+
subscription wire form (and other version-gated features) per peer.
|
|
140
|
+
Populated by `Mechanism::Null`, `Mechanism::Plain`, and
|
|
141
|
+
`Mechanism::Curve` via their handshake result hash.
|
|
142
|
+
- **`Codec::Greeting.read_from(io)`** — reads the 11-byte signature
|
|
143
|
+
phase first, validates the revision byte, then reads the rest of
|
|
144
|
+
the 64-byte greeting. A ZMTP/2.0 peer (revision `0x01`) is now
|
|
145
|
+
rejected loudly with `unsupported ZMTP revision 0x01 (ZMTP/2.x);
|
|
146
|
+
need revision >= 3`, instead of hanging forever in `read_exactly`
|
|
147
|
+
waiting for bytes that never arrive.
|
|
148
|
+
|
|
149
|
+
### Changed
|
|
150
|
+
|
|
151
|
+
- **Greeting error messages** refer to the ZMTP *revision byte*
|
|
152
|
+
(`0x03`) rather than a "version #{major}.#{minor}" — the byte at
|
|
153
|
+
offset 10 is the wire revision, which only accidentally matches the
|
|
154
|
+
spec major in ZMTP/3.x.
|
|
155
|
+
|
|
156
|
+
## 0.7.1 — 2026-04-14
|
|
157
|
+
|
|
158
|
+
### Changed
|
|
159
|
+
|
|
160
|
+
- **Short-frame read fast path.** `Frame.read_from` now fetches the
|
|
161
|
+
2-byte header (flags + first size byte) in a single `read_exactly`
|
|
162
|
+
call instead of two separate 1-byte reads. Short frames (≤255 bytes,
|
|
163
|
+
the vast majority of ZMTP traffic) now hit a 2-call read path
|
|
164
|
+
(header + body) instead of 3. Long frames read the remaining 7 size
|
|
165
|
+
bytes via the extracted `read_long_size` helper.
|
|
166
|
+
|
|
167
|
+
## 0.7.0 — 2026-04-13
|
|
168
|
+
|
|
169
|
+
### Added
|
|
170
|
+
|
|
171
|
+
- **Extension metadata hook on the handshake mechanisms.** `Mechanism::Null`,
|
|
172
|
+
`Mechanism::Plain`, and `Mechanism::Curve` expose a `metadata` accessor
|
|
173
|
+
(`Hash{String => String}`) that upper layers can populate before
|
|
174
|
+
`#handshake!`. Any entries are merged into the outgoing READY properties
|
|
175
|
+
(and INITIATE, for CURVE/PLAIN client side). `Codec::Command.ready` gained
|
|
176
|
+
a matching `metadata:` kwarg. Used by `omq-rfc-zstd` to advertise the
|
|
177
|
+
`X-Compression` property without forking the handshake code path.
|
|
178
|
+
|
|
179
|
+
- **`Connection#peer_properties`.** The full peer READY property hash is
|
|
180
|
+
now retained after a successful handshake (previously only Socket-Type,
|
|
181
|
+
Identity, and the X-QoS pair were extracted). Extensions can inspect
|
|
182
|
+
the peer's advertised properties to negotiate optional features.
|
|
183
|
+
Returned by all three mechanisms as `peer_properties:` in the
|
|
184
|
+
handshake result hash.
|
|
185
|
+
|
|
186
|
+
## 0.6.0 — 2026-04-12
|
|
187
|
+
|
|
188
|
+
### Changed
|
|
189
|
+
|
|
190
|
+
- **Consolidated empty-binary constant.** `Codec::Frame::EMPTY_BODY`
|
|
191
|
+
and `Codec::Command::EMPTY_DATA` are gone, replaced by a single
|
|
192
|
+
`Codec::EMPTY_BINARY` shared across the codec module. Anything
|
|
193
|
+
referencing the old constants needs to switch to
|
|
194
|
+
`Protocol::ZMTP::Codec::EMPTY_BINARY`.
|
|
195
|
+
|
|
196
|
+
## 0.5.1 — 2026-04-10
|
|
197
|
+
|
|
198
|
+
### Changed
|
|
199
|
+
|
|
200
|
+
- **Reduced allocations on hot paths.** Pre-computed `FLAG_BYTES` lookup
|
|
201
|
+
table eliminates `Integer#chr` + `String#b` per frame. `encode_message`
|
|
202
|
+
inlines wire encoding instead of creating throwaway Frame objects per
|
|
203
|
+
part. `write_frames` and `Command#to_body` skip redundant `.b` when
|
|
204
|
+
strings are already binary. `EMPTY_BODY` and `EMPTY_DATA` constants
|
|
205
|
+
replace per-call `"".b` allocations.
|
|
206
|
+
|
|
207
|
+
## 0.5.0 — 2026-04-10
|
|
208
|
+
|
|
209
|
+
### Fixed
|
|
210
|
+
|
|
211
|
+
- **Wire writes are now cancellation-safe.** `Connection#send_message`,
|
|
212
|
+
`#write_message`, `#write_messages`, `#write_wire`, and `#send_command`
|
|
213
|
+
each wrap their `@mutex.synchronize` block in
|
|
214
|
+
`Async::Task#defer_cancel`. A ZMTP frame is two `@io.write` calls
|
|
215
|
+
(header then body); under a socket-level barrier cascade (`barrier.stop`)
|
|
216
|
+
an `Async::Cancel` could previously land between those two writes,
|
|
217
|
+
leaving the peer with a header pointing at a body that never arrives
|
|
218
|
+
and an unrecoverable framer desync. `defer_cancel` holds the
|
|
219
|
+
cancellation until the write finishes, so cascading teardown only
|
|
220
|
+
unwinds at frame boundaries. Mutex protection is unchanged — it
|
|
221
|
+
guards against thread races; `defer_cancel` guards against fiber
|
|
222
|
+
cancellation. Non-Async callers (e.g. tests) fall through to the
|
|
223
|
+
unwrapped path.
|
|
224
|
+
|
|
225
|
+
## 0.4.0 — 2026-04-09
|
|
226
|
+
|
|
227
|
+
### Added
|
|
228
|
+
|
|
229
|
+
- **`Connection#write_messages`** — batched multipart send for work-stealing
|
|
230
|
+
send pumps. Dequeue a batch at once and write it under a single mutex
|
|
231
|
+
acquisition instead of one lock per message. Amortizes lock overhead on
|
|
232
|
+
high-throughput paths.
|
|
233
|
+
|
|
234
|
+
### Changed
|
|
235
|
+
|
|
236
|
+
- **Zero-alloc frame headers on the unencrypted hot send path.**
|
|
237
|
+
`#write_frames` used to allocate, per part, a `Codec::Frame` object, a
|
|
238
|
+
`.b` body copy, a 1-or-9-byte header String, and a concatenated wire
|
|
239
|
+
String (a copy of the entire body just to glue the header on). The body
|
|
240
|
+
copy was the dominant allocation — every 64 KB send produced a 64 KB
|
|
241
|
+
throwaway String, feeding the GC at ~1.2 GB/s under sustained load.
|
|
242
|
+
Headers are now packed into a reusable `@header_buf` via
|
|
243
|
+
`Array#pack(buffer:)`, header and body are written separately
|
|
244
|
+
(io-stream buffers them into one syscall per batch), the `Frame`
|
|
245
|
+
object is gone, and the body is no longer copied. `@mechanism.encrypted?`
|
|
246
|
+
is hoisted out of the per-frame loop. The encrypted path is unchanged —
|
|
247
|
+
CURVE/BLAKE3ZMQ still authenticate over the full encoded frame and need
|
|
248
|
+
a single wire String per part.
|
|
249
|
+
|
|
250
|
+
Bench impact downstream in omq (push_pull + router_dealer, 1 and 3 peers,
|
|
251
|
+
all transports): 48 improvements, 0 regressions across 72 measurements.
|
|
252
|
+
Peaks: `router_dealer tcp 3p 64B +40.7%`, `push_pull ipc 1p 64 KB +28.8%`
|
|
253
|
+
(crosses 1.3 GB/s).
|
|
254
|
+
|
|
255
|
+
## 0.3.0 — 2026-04-07
|
|
256
|
+
|
|
257
|
+
- Replace `[Async {}].each(&:wait)` with `Barrier` in tests.
|
|
258
|
+
- YARD documentation on all public methods and classes.
|
|
259
|
+
- Code style: two blank lines between methods and constants.
|
|
260
|
+
- Fix `#read_frame` decryption for non-CURVE encrypted mechanisms
|
|
261
|
+
(e.g. BLAKE3ZMQ). Previously only CURVE's `\x07MESSAGE`-wrapped command
|
|
262
|
+
frames were decrypted; inline-encrypted command frames (SUBSCRIBE, PING,
|
|
263
|
+
etc.) were silently dropped, breaking PUB/SUB over BLAKE3ZMQ.
|
|
264
|
+
|
|
265
|
+
- **Breaking:** `Mechanism::Curve` API is now kwargs-only:
|
|
266
|
+
`Curve.server(public_key:, secret_key:, crypto:)` and
|
|
267
|
+
`Curve.client(server_key:, crypto:)`. Client keys are optional — when
|
|
268
|
+
omitted, an ephemeral permanent keypair is auto-generated. INITIATE
|
|
269
|
+
always contains `C + vouch + metadata` per RFC 26.
|
|
270
|
+
- **Breaking:** Authenticator now receives a `Protocol::ZMTP::PeerInfo`
|
|
271
|
+
(with a `crypto::PublicKey`) via `#call`. The `#include?` duck-typing
|
|
272
|
+
is removed. Sends an ERROR command to the client on rejection.
|
|
273
|
+
- Add `Protocol::ZMTP::PeerInfo` shared across mechanisms.
|
|
274
|
+
- Add `#maintenance` to `Mechanism::Curve` for automatic cookie key rotation.
|
|
275
|
+
Returns `{ interval: 60, task: <Proc> }` on server-side mechanisms so the
|
|
276
|
+
host application can rotate the cookie key every 60 seconds, limiting the
|
|
277
|
+
forward secrecy exposure window.
|
|
278
|
+
|
|
279
|
+
## 0.2.0
|
|
280
|
+
|
|
281
|
+
- Add `Mechanism::Plain` — PLAIN authentication (RFC 24). Carries username and
|
|
282
|
+
password in a `HELLO` command during the handshake; no frame encryption.
|
|
283
|
+
Accepts an optional `authenticator:` callable on the server side for
|
|
284
|
+
credential validation.
|
|
285
|
+
|
|
286
|
+
## 0.1.2
|
|
287
|
+
|
|
288
|
+
- Check frame size against `max_message_size` before reading the body from the
|
|
289
|
+
wire. Previously, the entire frame was allocated into memory before the size
|
|
290
|
+
check, allowing a malicious peer to cause arbitrary memory allocation with a
|
|
291
|
+
single oversized frame header.
|
|
292
|
+
- Size limit applies to all frames including commands — an attacker cannot bypass
|
|
293
|
+
the check by setting the command flag.
|
|
294
|
+
|
|
295
|
+
## 0.1.1
|
|
296
|
+
|
|
297
|
+
- Initial public release.
|
data/README.md
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# Protocol::ZMTP
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/protocol-zmtp)
|
|
4
|
-
[](https://github.com/zeromq/omq.rb/actions/workflows/ci.yml)
|
|
5
5
|
|
|
6
|
-
ZMTP 3.1 wire protocol
|
|
6
|
+
ZMTP 3.1 wire protocol: codec, connection, NULL and CURVE mechanisms.
|
|
7
7
|
No runtime dependencies.
|
|
8
8
|
|
|
9
9
|
## What's in the box
|
|
10
10
|
|
|
11
|
-
- **Codec::Frame
|
|
12
|
-
- **Codec::Greeting
|
|
13
|
-
- **Codec::Command
|
|
14
|
-
- **Connection
|
|
15
|
-
- **Mechanism::Null
|
|
16
|
-
- **Mechanism::Curve
|
|
17
|
-
- **Z85
|
|
11
|
+
- **Codec::Frame**: ZMTP frame encode/decode (flags, size, body)
|
|
12
|
+
- **Codec::Greeting**: 64-byte greeting exchange
|
|
13
|
+
- **Codec::Command**: READY, PING/PONG, SUBSCRIBE, etc.
|
|
14
|
+
- **Connection**: per-connection frame I/O, handshake, PING/PONG
|
|
15
|
+
- **Mechanism::Null**: NULL security (no encryption)
|
|
16
|
+
- **Mechanism::Curve**: CurveZMQ (RFC 26) with pluggable crypto backend
|
|
17
|
+
- **Z85**: ZeroMQ RFC 32 encoding
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
```ruby
|
|
22
22
|
require "protocol/zmtp"
|
|
23
23
|
|
|
24
|
-
# NULL mechanism
|
|
24
|
+
# NULL mechanism, no encryption
|
|
25
25
|
conn = Protocol::ZMTP::Connection.new(
|
|
26
26
|
io,
|
|
27
27
|
socket_type: "REQ",
|
|
@@ -31,7 +31,7 @@ conn.handshake!
|
|
|
31
31
|
conn.send_message(["hello"])
|
|
32
32
|
msg = conn.receive_message
|
|
33
33
|
|
|
34
|
-
# CURVE mechanism
|
|
34
|
+
# CURVE mechanism, pass any NaCl-compatible backend
|
|
35
35
|
require "protocol/zmtp/mechanism/curve"
|
|
36
36
|
require "nuckle" # or: require "rbnacl"
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ server_mech = Protocol::ZMTP::Mechanism::Curve.server(
|
|
|
42
42
|
|
|
43
43
|
## CURVE crypto backend
|
|
44
44
|
|
|
45
|
-
`Mechanism::Curve` accepts a `crypto:` parameter
|
|
45
|
+
`Mechanism::Curve` accepts a `crypto:` parameter. Any module that
|
|
46
46
|
provides the NaCl API:
|
|
47
47
|
|
|
48
48
|
```ruby
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: protocol-zmtp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -18,6 +18,7 @@ executables: []
|
|
|
18
18
|
extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
|
+
- CHANGELOG.md
|
|
21
22
|
- LICENSE
|
|
22
23
|
- README.md
|
|
23
24
|
- lib/protocol/zmtp.rb
|
|
@@ -35,7 +36,7 @@ files:
|
|
|
35
36
|
- lib/protocol/zmtp/valid_peers.rb
|
|
36
37
|
- lib/protocol/zmtp/version.rb
|
|
37
38
|
- lib/protocol/zmtp/z85.rb
|
|
38
|
-
homepage: https://github.com/
|
|
39
|
+
homepage: https://github.com/zeromq/omq.rb/tree/main/gems/protocol-zmtp
|
|
39
40
|
licenses:
|
|
40
41
|
- ISC
|
|
41
42
|
metadata: {}
|
|
@@ -53,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
53
54
|
- !ruby/object:Gem::Version
|
|
54
55
|
version: '0'
|
|
55
56
|
requirements: []
|
|
56
|
-
rubygems_version: 4.0.
|
|
57
|
+
rubygems_version: 4.0.16
|
|
57
58
|
specification_version: 4
|
|
58
59
|
summary: ZMTP 3.1 wire protocol codec and connection
|
|
59
60
|
test_files: []
|