Class: Protocol::ZMTP::Mechanism::Null
- Inherits:
-
Object
- Object
- Protocol::ZMTP::Mechanism::Null
- Defined in:
- lib/protocol/zmtp/mechanism/null.rb
Overview
NULL security mechanism — no encryption, no authentication.
Performs the ZMTP 3.1 greeting exchange and READY command handshake.
Constant Summary collapse
- MECHANISM_NAME =
"NULL"
Instance Attribute Summary collapse
-
#metadata ⇒ Hash{String => String}
Extra READY properties an upper layer (e.g. an OMQ extension) wants this side to advertise.
Instance Method Summary collapse
-
#encrypted? ⇒ Boolean
False — NULL does not encrypt frames.
-
#handshake!(io, as_server:, socket_type:, identity:, qos: 0, qos_hash: "") ⇒ Hash
Performs the full NULL handshake over
io. -
#initialize ⇒ Null
constructor
A new instance of Null.
Constructor Details
#initialize ⇒ Null
Returns a new instance of Null.
20 21 22 |
# File 'lib/protocol/zmtp/mechanism/null.rb', line 20 def initialize @metadata = nil end |
Instance Attribute Details
#metadata ⇒ Hash{String => String}
Extra READY properties an upper layer (e.g. an OMQ extension) wants this side to advertise. Mutated before #handshake!.
17 18 19 |
# File 'lib/protocol/zmtp/mechanism/null.rb', line 17 def @metadata end |
Instance Method Details
#encrypted? ⇒ Boolean
Returns false — NULL does not encrypt frames.
90 |
# File 'lib/protocol/zmtp/mechanism/null.rb', line 90 def encrypted? = false |
#handshake!(io, as_server:, socket_type:, identity:, qos: 0, qos_hash: "") ⇒ Hash
Performs the full NULL handshake over io.
-
Exchange 64-byte greetings
-
Validate peer greeting (version, mechanism)
-
Exchange READY commands (socket type + identity + any extras)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/protocol/zmtp/mechanism/null.rb', line 37 def handshake!(io, as_server:, socket_type:, identity:, qos: 0, qos_hash: "") io.write(Codec::Greeting.encode(mechanism: MECHANISM_NAME, as_server: as_server)) io.flush peer_greeting = Codec::Greeting.read_from(io) unless peer_greeting[:mechanism] == MECHANISM_NAME raise Error, "unsupported mechanism: #{peer_greeting[:mechanism]}" end ready_cmd = Codec::Command.ready( socket_type: socket_type, identity: identity, qos: qos, qos_hash: qos_hash, metadata: @metadata, ) io.write(ready_cmd.to_frame.to_wire) io.flush frame = Codec::Frame.read_from(io) unless frame.command? raise Error, "expected command frame, got data frame" end peer_cmd = Codec::Command.from_body(frame.body) unless peer_cmd.name == "READY" raise Error, "expected READY command, got #{peer_cmd.name}" end props = peer_cmd.properties peer_socket_type = props["Socket-Type"] peer_identity = props["Identity"] || "" peer_qos = (props["X-QoS"] || "0").to_i peer_qos_hash = props["X-QoS-Hash"] || "" unless peer_socket_type raise Error, "peer READY missing Socket-Type" end { peer_socket_type: peer_socket_type, peer_identity: peer_identity, peer_qos: peer_qos, peer_qos_hash: peer_qos_hash, peer_properties: props, peer_major: peer_greeting[:major], peer_minor: peer_greeting[:minor], } end |