You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is no registry. Dispatch is four hardcoded functions
(_ethertype_class, _ip_protocol_class, udp_app_class, tcp_app_class) with dict literals inside them. There is no __init_subclass__, no decorator, no public hook.
Nobody can add a protocol to NETProtocols without editing library
source and sending a pull request. Every serious user eventually
meets a protocol we do not implement — MPLS, VXLAN, a proprietary
telemetry header, something from an industrial bus — and their only
options today are to fork or to leave.
This is the single biggest structural limitation in the codebase.
Why it is also the performance fix
A real registry is a module-level dict built once, which is exactly
what #82 needs. The two are the same change. Ship #82 as the
internal table, then generalise it here — or design them together.
Prior art worth following
Both leading designs in this space work this way: Wireshark's DissectorTable has dissectors register themselves against a parent
field value rather than parents hard-coding their children, and
gopacket does the same. Being able to extend the decode walk without
forking is the main practical reason people reach for scapy over a
small library.
Shape to aim for
@register(EtherType.MPLS)classMPLS(Protocol):
...
# and for numbers with no enum member yetregister(IPProtocol, 132, SCTP)
Design questions to settle first
Does registration mutate global state, or can a caller get an
isolated registry? Global is simpler; isolated is safer for
libraries that embed us and for test isolation.
What happens on a duplicate registration — raise, or last-wins?
Does the ipv6= gating generalise, or stay special-cased?
Target: 2.0.0 (Tier 2 — from codec to platform)
There is no registry. Dispatch is four hardcoded functions
(
_ethertype_class,_ip_protocol_class,udp_app_class,tcp_app_class) with dict literals inside them. There is no__init_subclass__, no decorator, no public hook.Nobody can add a protocol to NETProtocols without editing library
source and sending a pull request. Every serious user eventually
meets a protocol we do not implement — MPLS, VXLAN, a proprietary
telemetry header, something from an industrial bus — and their only
options today are to fork or to leave.
This is the single biggest structural limitation in the codebase.
Why it is also the performance fix
A real registry is a module-level dict built once, which is exactly
what #82 needs. The two are the same change. Ship #82 as the
internal table, then generalise it here — or design them together.
Prior art worth following
Both leading designs in this space work this way: Wireshark's
DissectorTablehas dissectors register themselves against a parentfield value rather than parents hard-coding their children, and
gopacket does the same. Being able to extend the decode walk without
forking is the main practical reason people reach for scapy over a
small library.
Shape to aim for
Design questions to settle first
isolated registry? Global is simpler; isolated is safer for
libraries that embed us and for test isolation.
ipv6=gating generalise, or stay special-cased?decode_frame()(Ship decode_frame() — the chain walker belongs in the library #88)accept a per-call override such as
decode_as={6969: DNS}?Acceptance criteria
source.
unchanged.
hardcoded functions.