pingora icon indicating copy to clipboard operation
pingora copied to clipboard

feat: Add ConnectionFilter trait for TCP-level connection filtering

Open jsulmont opened this issue 4 months ago • 10 comments

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 AcceptAllFilter maintains 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.

jsulmont avatar Aug 04 '25 08:08 jsulmont