erldistpy/erldistpy/flags.py
russell@unturf.com 8c9311f18a
phase 3: v6 distribution handshake
handshake(sock, our_name=..., cookie=...) drives the OTP 23+ dance over
a 2-byte length-prefixed frame stream:

  send_name (N)       client -> server
  recv_status (s)     server -> client
  recv_challenge (N)  server -> client
  challenge_reply (r) client -> server
  challenge_ack (a)   server -> client

Cookie digest formula md5(cookie ++ integer_to_list(challenge)) was
cross-checked against erlang:md5/1 output as a test reference.

Distribution flags in erldistpy/flags.py advertise the minimum useful
set: extended refs/pids, new fun tags, utf8 atoms, maps, big creation,
v6 handshake, unlink id, v4 node containers.

86 tests green: frame builders + parsers as pure functions, digest
reference, full live handshake against `erl -sname -setcookie`, and a
wrong-cookie rejection test.

Newer SHA-256 digest (DFLAG_MANDATORY_25_DIGEST) deferred until a peer
requires it.
2026-06-16 11:08:28 -04:00

60 lines
2 KiB
Python

"""Distribution capability flags.
Negotiated during the handshake; tell each peer what term types and
protocol features the other supports. We advertise the minimum useful
set for talking to an OTP 23+ Elixir node.
Source: ``$OTP/lib/kernel/include/dist.hrl`` and
https://www.erlang.org/doc/apps/erts/erl_dist_protocol.html
"""
from __future__ import annotations
DFLAG_PUBLISHED = 0x00000001
DFLAG_ATOM_CACHE = 0x00000002
DFLAG_EXTENDED_REFERENCES = 0x00000004
DFLAG_DIST_MONITOR = 0x00000008
DFLAG_FUN_TAGS = 0x00000010
DFLAG_DIST_MONITOR_NAME = 0x00000020
DFLAG_HIDDEN_ATOM_CACHE = 0x00000040
DFLAG_NEW_FUN_TAGS = 0x00000080
DFLAG_EXTENDED_PIDS_PORTS = 0x00000100
DFLAG_EXPORT_PTR_TAG = 0x00000200
DFLAG_BIT_BINARIES = 0x00000400
DFLAG_NEW_FLOATS = 0x00000800
DFLAG_UNICODE_IO = 0x00001000
DFLAG_DIST_HDR_ATOM_CACHE = 0x00002000
DFLAG_SMALL_ATOM_TAGS = 0x00004000
DFLAG_UTF8_ATOMS = 0x00010000
DFLAG_MAP_TAG = 0x00020000
DFLAG_BIG_CREATION = 0x00040000
DFLAG_SEND_SENDER = 0x00080000
DFLAG_BIG_SEQTRACE_LABELS = 0x00100000
DFLAG_EXIT_PAYLOAD = 0x00400000
DFLAG_FRAGMENTS = 0x00800000
DFLAG_HANDSHAKE_23 = 0x01000000
DFLAG_UNLINK_ID = 0x02000000
DFLAG_MANDATORY_25_DIGEST = 0x0000000400000000 # bit 34
DFLAG_SPAWN = 0x0000000100000000 # bit 32
DFLAG_NAME_ME = 0x0000000200000000 # bit 33
DFLAG_V4_NC = 0x0000000800000000 # bit 35
# What we advertise to peers. Enough to round-trip the term types we
# care about (atoms, integers, binaries, lists, tuples, pids, refs,
# maps) and to ride the v6 handshake.
DEFAULT_FLAGS = (
DFLAG_EXTENDED_REFERENCES
| DFLAG_FUN_TAGS
| DFLAG_EXTENDED_PIDS_PORTS
| DFLAG_NEW_FUN_TAGS
| DFLAG_EXPORT_PTR_TAG
| DFLAG_BIT_BINARIES
| DFLAG_NEW_FLOATS
| DFLAG_UTF8_ATOMS
| DFLAG_MAP_TAG
| DFLAG_BIG_CREATION
| DFLAG_HANDSHAKE_23
| DFLAG_UNLINK_ID
| DFLAG_V4_NC
)