Module: Protocol::ZMTP::Codec::Greeting

Defined in:
lib/protocol/zmtp/codec/greeting.rb

Overview

ZMTP 3.1 greeting encode/decode.

The greeting is always exactly 64 bytes:

Offset  Bytes  Field
0       1      0xFF (signature start)
1-8     8      0x00 padding
9       1      0x7F (signature end)
10      1      major version
11      1      minor version
12-31   20     mechanism (null-padded ASCII)
32      1      as-server flag (0x00 or 0x01)
33-63   31     filler (0x00)

Constant Summary collapse

SIZE =
64
SIGNATURE_START =
0xFF
SIGNATURE_END =
0x7F
VERSION_MAJOR =
3
VERSION_MINOR =
1
MECHANISM_OFFSET =
12
MECHANISM_LENGTH =
20
AS_SERVER_OFFSET =
32

Class Method Summary collapse

Class Method Details

.decode(data) ⇒ Hash

Decodes a ZMTP greeting.

Parameters:

  • data (String)

    64-byte binary greeting

Returns:

  • (Hash)

    { major:, minor:, mechanism:, as_server: }

Raises:

  • (Error)

    on invalid greeting



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
# File 'lib/protocol/zmtp/codec/greeting.rb', line 49

def self.decode(data)
  raise Error, "greeting too short (#{data.bytesize} bytes)" if data.bytesize < SIZE

  data = data.b

  unless data.getbyte(0) == SIGNATURE_START && data.getbyte(9) == SIGNATURE_END
    raise Error, "invalid greeting signature"
  end

  major = data.getbyte(10)
  minor = data.getbyte(11)

  unless major >= 3
    raise Error, "unsupported ZMTP version #{major}.#{minor} (need >= 3.0)"
  end

  mechanism = data.byteslice(MECHANISM_OFFSET, MECHANISM_LENGTH).delete("\x00")
  as_server = data.getbyte(AS_SERVER_OFFSET) == 1

  {
    major:     major,
    minor:     minor,
    mechanism: mechanism,
    as_server: as_server,
  }
end

.encode(mechanism: "NULL", as_server: false) ⇒ String

Encodes a ZMTP 3.1 greeting.

Parameters:

  • mechanism (String) (defaults to: "NULL")

    security mechanism name (e.g. “NULL”)

  • as_server (Boolean) (defaults to: false)

    whether this peer is the server

Returns:

  • (String)

    64-byte binary greeting



35
36
37
38
39
40
41
# File 'lib/protocol/zmtp/codec/greeting.rb', line 35

def self.encode(mechanism: "NULL", as_server: false)
  buf = "\xFF".b + ("\x00" * 8) + "\x7F".b
  buf << [VERSION_MAJOR, VERSION_MINOR].pack("CC")
  buf << mechanism.b.ljust(MECHANISM_LENGTH, "\x00")
  buf << (as_server ? "\x01" : "\x00")
  buf << ("\x00" * 31)
end