Skip to content

Fix pktinfo send cmsg_level/cmsg_type (IPPROTO_IP / IP_PKTINFO) - #238

Merged
swhitty merged 1 commit into
swhitty:mainfrom
ianegordon:ian/tvt-1064-pktinfo-send-uses-wrong-cmsg_levelcmsg_type-should-be
Aug 13, 2026
Merged

Fix pktinfo send cmsg_level/cmsg_type (IPPROTO_IP / IP_PKTINFO)#238
swhitty merged 1 commit into
swhitty:mainfrom
ianegordon:ian/tvt-1064-pktinfo-send-uses-wrong-cmsg_levelcmsg_type-should-be

Conversation

@ianegordon

Copy link
Copy Markdown
Contributor

Problem

The send-side IP_PKTINFO/IPV6_PKTINFO control messages built by Socket.withPacketInfoControl set:

header.pointee.cmsg_level = SOL_SOCKET
header.pointee.cmsg_type  = Socket.ipproto_ip   // protocol number in the type field

Per cmsg(3), cmsg_level is the originating protocol and cmsg_type the protocol-specific type. A pktinfo ancillary message requires IPPROTO_IP / IP_PKTINFO (RFC 3542 §6 for IPv6: "the socket option and cmsghdr level will be IPPROTO_IPV6, the type will be IPV6_PKTINFO"). The library's own receive path (getPacketInfoControl) already matches on exactly those pairs — so send and receive were mutually inconsistent, and send(message:to:interfaceIndex:from:) could not apply source-address/interface selection.

Change

Set cmsg_level = IPPROTO_IP / cmsg_type = IP_PKTINFO (IPv6: IPPROTO_IPV6 / IPV6_PKTINFO) on the send side, matching the receive path. Depends on the ipv6_pktinfo constant fix from #233 (already on main): with the correct cmsg level the kernel interprets cmsg_type for the first time, so both fixes are needed together for IPv6 sends to succeed on Darwin.

Tests

  • Deterministic unit tests asserting the exact level/type pairs against the platform constants for IPv4 and IPv6 (verified to fail against the previous values).
  • Loopback round-trip tests: datagrams sent with explicit packet info are received with the expected payload for both IPv4 and IPv6.

Full suite passes (464 tests).

🤖 Generated with Claude Code

Send-side IP_PKTINFO/IPV6_PKTINFO control messages used SOL_SOCKET as
the cmsg_level and the protocol number as the cmsg_type, inconsistent
with the library's own receive path. Set IPPROTO_IP/IP_PKTINFO and
IPPROTO_IPV6/IPV6_PKTINFO as required by ip(7) and RFC 3542 §6.

Add deterministic tests asserting the exact level/type pairs against
platform constants (verified to fail against the previous values),
plus loopback round-trip smoke tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ianegordon
ianegordon marked this pull request as ready for review August 11, 2026 00:02
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.72%. Comparing base (71dcb81) to head (8337bfc).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #238      +/-   ##
==========================================
+ Coverage   93.00%   93.72%   +0.71%     
==========================================
  Files          72       72              
  Lines        3748     3777      +29     
==========================================
+ Hits         3486     3540      +54     
+ Misses        262      237      -25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@swhitty

swhitty commented Aug 13, 2026

Copy link
Copy Markdown
Owner

nice, thank you

@swhitty
swhitty merged commit bd32d43 into swhitty:main Aug 13, 2026
24 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants