> IIRC, the connections-per-ip code isn't in a plugin right now -- it's > part of the main binary -- because it requires some sort of shared > state which we don't have for plugins.
The checks do exist in the binaries but they don't have to, you can use $arg{child_addrs} and $arg{remote_ip} in hook_pre_connection to get at it, at least in prefork, we've been doing it forever. Our code is heavily modified for our db-based prefs but it's a lot like this: my %per_ip_limits = ( # fake magic per-ip config hashref 1.2.3.4 => 10, ); my %class_c_limits = ( 1.2.3.4 => 20, ); sub ip_to_int { my ( $ip ) = @_; $ip = inet_aton($ip) if length($ip) > 4; return unpack 'N', $ip; } sub hook_pre_connection { my ( $self, $txn, %arg ) = @_; return NEXT unless @{ $arg{child_addrs }; my $ip_limit = $per_ip_limits{ $arg{remote_ip} } || 5; return DENYSOFT_DISCONNECT, 'Too many connections from your IP' if ( grep { $_ eq $arg{remote_ip} } @{$arg{child_addrs}} ) > $ip_limit; my $c_limit = $class_c_limits{ $arg{remote_ip} } || 10; my $ip = ip_to_int( $arg{remote_ip} ); my $mask = $ip & 0xffffff00; return DENYSOFT_DISCONNECT, 'Too many connections from your class C' if ( grep {(ip_to_int($_)&0xffffff00) == $mask} @{$arg->{child_addrs}} ) > $c_limit; return NEXT; } another interesting thing we support is allowing people to set a custom max concurrency override for an arbitrary cidr; when an IP matches the CIDR, we check how many other child_addr's match the same CIDR instead of checking the other limits. We use Net::CIDR::Lite::Span for this business though so it's probably less efficient than the above. We also use hook_pre_connection to implement global connection limits, which allows us to defer and write an entry to our DB logs when the limit is exceeded, rather than just not responding. This is way less efficient though, and we've had to contend with it snowballing when the system becomes so busy that the db is slow. Oh well, someday we'll switch to async :) -Jared