Skip to content

[client] Refactor/optimise raw socket headers#5174

Merged
pappz merged 7 commits intomainfrom
refactor/optimise-raw-socket-headers
Jan 28, 2026
Merged

[client] Refactor/optimise raw socket headers#5174
pappz merged 7 commits intomainfrom
refactor/optimise-raw-socket-headers

Conversation

@pappz
Copy link
Copy Markdown
Collaborator

@pappz pappz commented Jan 24, 2026

Describe your changes

Pre-create and reuse packet headers to eliminate per-packet allocations.

Issue ticket number and link

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • Refactor
    • Improved packet header management and per-endpoint header preparation for more reliable UDP packet transmission.
    • Enhanced IPv4/IPv6 raw socket selection and packet serialization for more consistent sending behavior.
    • Removed legacy packet serialization path, simplifying and streamlining internal transmission flow.

✏️ Tip: You can customize this high-level summary in your review settings.

pappz added 3 commits January 23, 2026 21:42
Add IPv6 packet header support in UDP raw socket proxy
to handle both IPv4 and IPv6 source addresses.
Refactor error handling in proxy bind implementations
to validate endpoints before acquiring locks.
The sendPkg function now detects IP version and creates appropriate IPv4 or IPv6 headers, preventing IPv6 addresses from being placed into IPv4 packet headers.
@pappz pappz changed the base branch from main to fix/ipv6-proxy January 24, 2026 19:58
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 24, 2026

📝 Walkthrough

Walkthrough

Refactors eBPF WireGuard proxy packet path: proxy.go removes gopacket-based serialization; wrapper.go introduces PacketHeaders, moves packet header construction and raw-socket send logic into ProxyWrapper, and adds raw connection selection per endpoint.

Changes

Cohort / File(s) Summary
Gopacket removal
client/iface/wgproxy/ebpf/proxy.go
Removed gopacket imports, local loopback address constants, SerializeOptions, and the sendPkg function that serialized UDP packets via gopacket/raw sockets.
Header management & raw-socket send
client/iface/wgproxy/ebpf/wrapper.go
Added PacketHeaders type and NewPacketHeaders(localWGListenPort int, endpoint *net.UDPAddr) (*PacketHeaders, error). Extended ProxyWrapper with headers, headerCurrentUsed, and rawConn fields. Added sendPkg(data []byte, header *PacketHeaders) error and selectRawConn(header *PacketHeaders) net.PacketConn. Updated AddTurnConn, Work, and RedirectAs to create/select PacketHeaders and validate/select raw connections. Added related error variables and gopacket/layers imports.

Sequence Diagram(s)

sequenceDiagram
    participant EBPF as eBPF program
    participant Proxy as ProxyWrapper
    participant Headers as PacketHeaders
    participant Raw as rawConn (net.PacketConn)
    participant Net as Network

    EBPF->>Proxy: hand off UDP payload
    Proxy->>Headers: select / create headers (headerCurrentUsed)
    Proxy->>Raw: selectRawConn(headerCurrentUsed)
    Proxy->>Raw: sendPkg(payload + headers)
    Raw->>Net: write packet to network
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • lixmal

Poem

🐰 I stitched headers, snug and neat,
I bound UDP with careful feet,
Gopacket hopped away today,
Raw sockets hum and lead the way,
🥕—a tiny rabbit's packet beat

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: refactoring/optimizing raw socket headers.
Description check ✅ Passed The description follows the template with main change explained, refactor checkbox marked, and documentation status addressed; no issue link is a minor omission.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@client/iface/wgproxy/ebpf/wrapper.go`:
- Around line 244-262: The sendPkg method in ProxyWrapper should defensively
validate that the packetSender argument is not nil before dereferencing its
fields; add a nil check at the start of sendPkg (returning a descriptive error
like "nil packetSender") and ensure the deferred cleanup that calls
packetSender.layerBuffer.Clear is only executed when packetSender and
packetSender.layerBuffer are non-nil (or move the defer after the nil check) to
avoid a nil pointer dereference when accessing packetSender.layerBuffer,
packetSender.ipH, packetSender.udpH, and packetSender.localHostAddr.
🧹 Nitpick comments (1)
client/iface/wgproxy/ebpf/wrapper.go (1)

21-76: Code duplication with rawsocket.go's prepareHeaders.

The logic in NewPacketHeaders closely mirrors prepareHeaders in rawsocket.go. Consider extracting the shared IPv4/IPv6 header construction into a common utility to reduce duplication and ensure consistency.

Comment thread client/iface/wgproxy/ebpf/wrapper.go
Base automatically changed from fix/ipv6-proxy to main January 26, 2026 13:03
# Conflicts:
#	client/iface/wgproxy/ebpf/proxy.go
#	client/iface/wgproxy/ebpf/wrapper.go
#	client/iface/wgproxy/udp/rawsocket.go
Comment thread client/iface/wgproxy/ebpf/proxy.go
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
client/iface/wgproxy/ebpf/wrapper.go (1)

159-175: Keep rawConn aligned with headerCurrentUsed on resume.
Work() resets headerCurrentUsed to p.headers but leaves rawConn unchanged. If a prior RedirectAs() switched to IPv6, this can serialize IPv4 headers while writing to the IPv6 raw socket (or vice‑versa), causing drops/EINVAL. Either preserve the redirected header or update rawConn after the assignment.

🐛 Suggested fix (keeps redirected header if present and syncs rawConn)
-	p.headerCurrentUsed = p.headers
+	if p.headerCurrentUsed == nil {
+		p.headerCurrentUsed = p.headers
+	}
+	p.rawConn = p.selectRawConn(p.headerCurrentUsed)

Update rawConn when resetting to original headers in Work() to maintain consistency between packet headers and the selected raw socket connection.
@sonarqubecloud
Copy link
Copy Markdown

@pappz pappz merged commit b55262d into main Jan 28, 2026
38 checks passed
@pappz pappz deleted the refactor/optimise-raw-socket-headers branch January 28, 2026 14:07
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