Skip to content

gossvf: zero ContactInfos with multicast auxiliary sockets#8962

Merged
jherrera-jump merged 6 commits intofiredancer-io:mainfrom
Rhovian:reject-mcast-contact-info
Apr 8, 2026
Merged

gossvf: zero ContactInfos with multicast auxiliary sockets#8962
jherrera-jump merged 6 commits intofiredancer-io:mainfrom
Rhovian:reject-mcast-contact-info

Conversation

@Rhovian
Copy link
Copy Markdown
Contributor

@Rhovian Rhovian commented Mar 19, 2026

Summary

Zero out ContactInfo fields from gossip where any auxiliary socket (TVU, TPU, repair, etc.) has a multicast IP address. The gossip socket was already validated against multicast; this extends the check to all other sockets.

  • Adds a multicast check loop over all ContactInfo sockets in verify_addresses()
  • Intentionally scoped to multicast only — does not enforce public/private policy on non-gossip sockets
  • IPv6 sockets are skipped (not coerced to zero), preserving existing behavior for peers advertising IPv6

Resolves #8396

cc @mmcgee-jump

Gossip already validates the gossip socket address against multicast,
but non-gossip sockets (TVU, TPU, repair, etc.) were accepted without
checking. A malicious peer could advertise a multicast address for
these sockets, causing the validator to send traffic to unintended
destinations.

Resolves firedancer-io#8396
Copilot AI review requested due to automatic review settings March 19, 2026 00:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends Firedancer’s gossip verification (gossvf) to reject ContactInfo messages that advertise multicast IPv4 addresses on any auxiliary socket (e.g., TPU/TVU/repair), mitigating the risk of a peer inducing unintended multicast traffic.

Changes:

  • Adds a multicast IPv4 check across all ContactInfo sockets during verify_addresses().
  • Keeps existing behavior for IPv6 sockets by skipping them (no coercion to zero).

Comment thread src/discof/gossip/fd_gossvf_tile.c Outdated
@mmcgee-jump
Copy link
Copy Markdown
Contributor

This behavior diverges from Agave, so I need to review why that is and how they solve this

Copy link
Copy Markdown
Contributor

@mmcgee-jump mmcgee-jump left a comment

Choose a reason for hiding this comment

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

.

@Rhovian
Copy link
Copy Markdown
Contributor Author

Rhovian commented Mar 19, 2026

This behavior diverges from Agave, so I need to review why that is and how they solve this

My read of Agave is that it already sanitizes all ContactInfo sockets during deserialization, not just gossip. In TryFrom, the loop at L569 iterates every SocketEntry and calls sanitize_socket(), which rejects multicast via is_multicast(). This covers all socket types — TPU, TVU, repair, etc.

The difference is in severity: Agave silently omits the bad socket from the cache (L578-580) but still accepts the ContactInfo into CRDS — only a bad gossip socket triggers full rejection via verify_gossip_addr(). This PR is stricter: it drops the entire ContactInfo at L662, which seems like the right call given there's no legitimate multicast use case — Agave's own codebase explicitly states "Agave does not currently support multicast," and turbine/repair/TPU are all unicast.

I'll leave the PR open as is lmk what you think @mmcgee-jump

@ripatel-fd
Copy link
Copy Markdown
Contributor

This PR is stricter: it drops the entire ContactInfo

Firedancer aims to match Agave's CRDS filtering rules exactly. If either side filters more aggressively it would just cause persistent unnecessary traffic, because the protocol gets into a loop where the more lenient side keeps retransmitting the dropped value to the more aggressively-filtering side over and over.

@Rhovian
Copy link
Copy Markdown
Contributor Author

Rhovian commented Mar 20, 2026

This PR is stricter: it drops the entire ContactInfo

Firedancer aims to match Agave's CRDS filtering rules exactly. If either side filters more aggressively it would just cause persistent unnecessary traffic, because the protocol gets into a loop where the more lenient side keeps retransmitting the dropped value to the more aggressively-filtering side over and over.

Given this, the divergence is entirely Multicast non-gossip socket (TVU, repair, etc.):

  • agave: accept ContactInfo into CRDS, silently omit bad socket from cache
  • firedancer: drop the entire ContactInfo

So I think to reach parity firedancer should also accept ContactInfo into CRDS but sanitize at deserialization time. I'd implement it by adjusting the current pr's drop to in place zeroing, something like:

if( fd_ip4_addr_is_mcast( sock->ip4 ) ) {
  sock->ip4 = 0;
  sock->port = 0;
}

if yall think that makes sense, i'll adjust the PR.

edit, parity caveats:

  • txsend and the repair path currently treat a zeroed socket as “keep the last cached endpoint” rather than “socket absent”
  • multicast-only auxiliary-socket sanitize still wouldn’t fully match Agave, because Agave treats auxiliary IPv4 sockets with ip4 == 0 and nonzero port as absent, while Firedancer would still retain them

Copy link
Copy Markdown
Contributor

@cmoyes-jump cmoyes-jump left a comment

Choose a reason for hiding this comment

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

This is potentially consensus breaking with Agave, as written.

This would have to be a feature gate to coordinate changes in both validators without breaking behavioral consistency.

Copilot AI review requested due to automatic review settings March 21, 2026 19:43
@Rhovian
Copy link
Copy Markdown
Contributor Author

Rhovian commented Mar 21, 2026

Updated to match Agave's CRDS filtering: non-gossip multicast sockets are now zeroed in place (ip4=0, port=0) instead of dropping the entire ContactInfo.

Deffered for follow up work: txsend and repair treat zeroed sockets as "keep old cached value" rather than "socket absent"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the gossvf validation path for incoming gossip ContactInfo CRDS values by adding multicast filtering for non-gossip sockets (TPU/TVU/repair/etc.) during verify_addresses().

Changes:

  • Add a loop over all ContactInfo sockets to detect multicast IPv4 addresses.
  • Zero out (ip4=0, port=0) any non-IPv6 socket that advertises a multicast IPv4 address.

Comment thread src/discof/gossip/fd_gossvf_tile.c Outdated
Comment thread src/discof/gossip/fd_gossvf_tile.c Outdated
@Rhovian Rhovian changed the title gossvf: reject ContactInfos with multicast auxiliary sockets gossvf: zero ContactInfos with multicast auxiliary sockets Mar 21, 2026
copilot adjust comment

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 21, 2026 19:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread src/discof/gossip/fd_gossvf_tile.c
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@jherrera-jump jherrera-jump dismissed stale reviews from cmoyes-jump and mmcgee-jump April 8, 2026 18:18

filtering now matches

@jherrera-jump jherrera-jump merged commit c0208b7 into firedancer-io:main Apr 8, 2026
21 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.

Gossip should reject ContactInfos with multicast IP address

6 participants