Skip to content

eep: add TCP support for HEP3 listen - #583

Merged
Kaian merged 4 commits into
irontec:masterfrom
darwvin-dev:feat/hep3-tcp-listener-501
Oct 16, 2026
Merged

Kaian merged 4 commits into
irontec:masterfrom
darwvin-dev:feat/hep3-tcp-listener-501

Conversation

@darwvin-dev

Copy link
Copy Markdown
Contributor

Summary

Add TCP support for the HEP listen socket, as requested in #501.

A new eep.listen.proto setting (udp or tcp, default udp) selects the listen socket protocol, and it is also available in the EEP/HEP settings dialog. The -L url protocol prefix now sets it:

sngrep -L tcp:0.0.0.0:9060

Existing udp: urls and eep.listen.* settings keep working as before.

TCP clients are handled from the existing EEP capture thread with poll() (up to 64 simultaneous connections), so no new threads are added. Each connection keeps its own buffer until a full HEP3 packet is received, using the HEP3 total length field, so packets split across several reads or several packets in a single read are parsed properly. Connections sending data that is not HEP3, or packets that do not fit in the capture buffer, are closed without affecting other clients. HEPv2 has no total length field, so TCP listen requires eep.listen.version 3.

Other fixes in the HEP listen path, as separate commits:

  • Packets that failed to parse were destroyed and then written to the output file (-O). Now only parsed packets are dumped.
  • The listen socket was always created as IPv4 UDP, so an IPv6 eep.listen.address failed to bind. It now uses the address family returned by getaddrinfo.
  • HEP3 packets shorter than the header, longer than the received data, or with chunks that do not fit in the packet are dropped. The received authentication key is now NUL terminated before it is compared.

Closes #501

Validation

  • ./configure --enable-eep --enable-ipv6 --with-pcre2
  • make -j$(nproc): no new warnings. CMake build with -DUSE_EEP=ON also builds.
  • make check: 14/14 passed
  • End-to-end with sngrep -N -F -L tcp:127.0.0.1:19061 -O tcp.pcap and a Python HEP3 sender. tshark found every expected Call-ID in the output pcap:
    • one packet sent in 3 pieces, with the header split
    • two full packets plus part of a third in one send(), and the rest later
    • an idle client holding a partial packet, while other clients keep being served
    • non-HEP data, a 60000-byte length and a length below the header size: only those connections are closed
    • a new client after the bad ones still works
    • after all clients disconnect, only the listen socket is still open (no fd leak)
  • 70 simultaneous clients: 64 are kept and the rest are closed.
  • -L udp:127.0.0.1:19062 still receives HEP3 over UDP. IPv6 (::1) was tested over TCP and UDP with eep.listen.* settings in an rc file.
  • -L tcp: with eep.listen.version 2 prints EEP server: TCP listen requires HEP version 3.
  • ASan/UBSan build: 300 TCP connections and 3000 UDP datagrams of mutated and random HEP3 data, sent in random chunks. No ASan reports.

🤖 Generated with Claude Code

@Kaian Kaian left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! 💯

I was not able to test TCP receiver (UDP still works as expected). It would be nice to include TCP also in the HEP sender logic!! :)

Thanks!

Comment thread src/capture_eep.c Resolved
Comment thread src/curses/ui_settings.c Resolved
darwvin-dev and others added 4 commits October 16, 2026 09:43
The listen socket was always created as an IPv4 UDP socket, so binding
an IPv6 eep.listen.address failed. Use the family and protocol returned
by getaddrinfo, check the created server socket instead of the client
one, and free the resolved address list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add eep.listen.proto setting (udp or tcp, default udp) to select the
protocol of the HEP listen socket. The -L url protocol prefix now sets
it, so -L tcp:X.X.X.X:XXXX listens for HEP3 over TCP while existing
udp: urls and settings keep working as before.

TCP clients are handled from the existing EEP capture thread using
poll(), up to 64 simultaneous connections. Each connection has its own
buffer where received data is stored until a full HEP3 packet is
available, using the HEP3 total length field, so packets split in
several reads or several packets in a single read are parsed properly.
Connections sending data that is not HEP3 or packets that do not fit in
the buffer are closed.

HEPv2 has no total length field, so TCP listen requires HEP version 3.

Closes irontec#501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HEP3 packets are received from the network, but the parser trusted the
total length and chunk lengths found in them: chunks could be read past
the received data or the packet total length, chunks shorter than their
header produced negative payload sizes, and received authentication keys
were compared without a string terminator.

Drop HEP3 packets that are shorter than the HEP3 header, longer than the
received data, or contain chunks that do not fit in the packet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Homer can receive HEP over TCP, but -H only accepted udp: urls. Add
an eep.send.proto setting, filled from the -H url scheme, so captured
packets can also be sent through a TCP connection.

HEPv2 has no length field to frame packets on a stream, so TCP send
requires HEP version 3. Full frames are written under a lock, so
packets sent from different capture threads never interleave on the
connection, and HEP3 packets longer than the 16-bit length fields
allow are not sent.

While here, release the resolved address and the socket when the
connection fails, and return the send result from the v2 sender.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kaian
Kaian force-pushed the feat/hep3-tcp-listener-501 branch from 56a18d9 to fe3a8ec Compare October 16, 2026 08:02
@Kaian
Kaian merged commit d79fb67 into irontec:master Oct 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Feature-Request: Add TCP support for HEP3 listen

2 participants