feat: Add ConnectionFilter trait for TCP-level connection filtering
feat: Add ConnectionFilter trait for TCP-level connection filtering
Summary
Implements connection filtering at the TCP level before TLS handshake, allowing early rejection of unwanted connections to save resources.
Problem
Currently, Pingora has no mechanism to filter connections before the TLS handshake. All filtering must happen after TLS negotiation completes, which means:
- Unwanted connections waste resources on expensive TLS handshakes
- No protection against connection-level attacks before TLS
- IP filtering and geoblocking happen too late in the connection lifecycle
Solution
Adds a ConnectionFilter trait that allows custom filtering logic:
#[async_trait]
pub trait ConnectionFilter: Send + Sync {
async fn should_accept(&self, addr: &SocketAddr) -> bool {
true // Default: accept all
}
}
Usage
let mut service = Service::new("my_service", my_app);
service.set_connection_filter(Arc::new(MyCustomFilter));
Feature Flag
This PR includes a connection_filter feature flag to make the functionality opt-in:
- When disabled (default): No overhead, no async trait allocations
- When enabled: Full connection filtering capability
- API remains the same in both cases for compatibility
Enable with: cargo build --features connection_filter
Features
- Filters connections at TCP accept, before TLS handshake
- Async trait allows for complex filtering logic (database lookups, rate limiting, etc.)
- Default
AcceptAllFiltermaintains backward compatibility - Minimal performance impact - single trait call per connection
- Rejected connections are dropped immediately without further processing
Closes #669 and possibly #297
Testing
Tests for connection filtering in pingora-core.
I think this PR makes total sense. Would you be open to feature flagging this out? The idea would be for people (like us) to avoid paying the cost of async trait allocations if its not in use?
I think this PR makes total sense. Would you be open to feature flagging this out? The idea would be for people (like us) to avoid paying the cost of async trait allocations if its not in use?
Hi @johnhurt of course -- should have thought about it 👍🏻
Hi @johnhurt -- I've pushed a few commits towards feature gating connection filtering.
Hi @johnhurt — just checking in on the connection filter PR.
Feature-flagging is in place, and the rest should be straightforward.
Only perf caveat is if someone blocks in the callback — but that'd be very rude, and on them i think
Just wanted to mention that we've deployed this connection filtering feature from my fork in a production environment (enterprise utility infrastructure). It's been professionally penetration tested and performed well under sustained high-load conditions during security testing.
TL;DR Working great in real-world conditions! 👍
Awesome, yeah. This looks great. I'll get it ingested into our local copy, and it should appear next week in our sync.
Awesome, yeah. This looks great. I'll get it ingested into our local copy, and it should appear next week in our sync.
Thank you!! (<3 pingora)
Hi @johnhurt would you know when/if this PR is going to make it into main? I was surprised to see that 0.6 doesn't have that feature. Do I need to do anything? Thank you!
No, the delay is on me. We accepted the pr for internal review and made some minor changes. I just need to shepherd it through the rest of the process. Thanks for your patience
No, the delay is on me. We accepted the pr for internal review and made some minor changes. I just need to shepherd it through the rest of the process. Thanks for your patience
No worries at all, and thanks again for sharing Pingora :-)