Add a fork fence for max concurrent in-flight (post-login) requests
authorMike Rylander <mrylander@gmail.com>
Fri, 13 Sep 2013 16:04:18 +0000 (12:04 -0400)
committerMike Rylander <mrylander@gmail.com>
Fri, 13 Sep 2013 16:04:18 +0000 (12:04 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
SIPServer.pm

index 5e577c1..3448ed5 100644 (file)
@@ -99,12 +99,16 @@ push @parms,
 #
 # The Multiplex module ignores all runtime params, and triggers an
 # alternate implementation of the processing loop.  See the Net::Server
-# personality documentation for details.
+# personality documentation for details. The max-concurrent parameter
+# can be used here to limit the number of concurrent in-flight requests
+# to avoid a fork-bomb DoS situation.  The default is 256.
 #
+my $max_concurrent = 256;
 if (defined($config->{'server-params'})) {
     while (my ($key, $val) = each %{$config->{'server-params'}}) {
         push @parms, $key . '=' . $val;
         @ISA = ('Net::Server::'.$val) if ($key eq 'personality');
+        $max_concurrent = $val if ($key eq 'max-concurrent');
     }
 }
 
@@ -194,6 +198,12 @@ sub mux_input {
     # check for kids that went away
     REAPER();
 
+    if ($kid_count >= $max_concurrent) {
+        # XXX should we say something to the client? maybe wait and try again?
+        syslog('LOG_ERR', "Unwilling to fork new child process, at least $max_concurrent already ongoing");
+        return;
+    }
+
     my $self;
     if (!$active_connections{$conn_id}) { # Brand new connection, log them in
         $self = $mself->{net_server};