diff options
author | plumbeo <plumbeo@users.noreply.github.com> | 2017-01-05 18:04:00 +0100 |
---|---|---|
committer | plumbeo <plumbeo@users.noreply.github.com> | 2017-01-05 18:19:40 +0100 |
commit | 47f967856ef25557d87430026e8b208a8852381f (patch) | |
tree | 1ab5f2676d3a7f1575a58c24e2049458fbdc4144 /src | |
parent | ea02e3cf5d54c9f1ebbe09d9fa5522c5c9916876 (diff) | |
download | pfsense-47f967856ef25557d87430026e8b208a8852381f.zip pfsense-47f967856ef25557d87430026e8b208a8852381f.tar.gz |
Captive portal: make captiveportal_disconnect_all() faster
captiveportal_disconnect_all() removes the users one at a time and in some cases, when many hundreds of users are connected, can take up to several dozens of seconds to complete.
Instead of looping through all users, send all the accounting information, reset the user database and delete all the active rules and reinit them. Use locking to prevent new users from logging in until the function ends.
Diffstat (limited to 'src')
-rw-r--r-- | src/etc/inc/captiveportal.inc | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/src/etc/inc/captiveportal.inc b/src/etc/inc/captiveportal.inc index 449d75c..bc192eb 100644 --- a/src/etc/inc/captiveportal.inc +++ b/src/etc/inc/captiveportal.inc @@ -1082,35 +1082,31 @@ function captiveportal_disconnect_all($term_cause = 6, $logoutReason = "DISCONNE global $g, $config, $cpzone, $cpzoneid; /* check if we're pruning old entries and eventually wait */ - $rcprunelock = try_lock("rcprunecaptiveportal{$cpzone}", 60); + $rcprunelock = try_lock("rcprunecaptiveportal{$cpzone}", 15); /* if we still don't have the lock, unlock forcefully and take it */ if (!$rcprunelock) { - log_error("CP zone ${cpzone}: could not obtain the lock for more than 60 seconds, lock taken forcefully to disconnect all users"); + log_error("CP zone ${cpzone}: could not obtain the lock for more than 15 seconds, lock taken forcefully to disconnect all users"); unlock_force("rcprunecaptiveportal{$cpzone}"); $rcprunelock = lock("rcprunecaptiveportal{$cpzone}", LOCK_EX); } - $radiussrvs = captiveportal_get_radius_servers(); - $cpdb = captiveportal_read_db(); + /* take a lock so new users won't be able to log in */ + $cpdblck = lock("captiveportaldb{$cpzone}", LOCK_EX); + + captiveportal_radius_stop_all($term_cause, $logoutReason); - /* remove immediately the active users from the database to avoid races */ + /* remove users from the database */ + $cpdb = captiveportal_read_db(); $unsetindexes = array_column($cpdb,5); if (!empty($unsetindexes)) { captiveportal_remove_entries($unsetindexes); } - foreach ($cpdb as $cpentry) { - if (empty($cpentry[11])) { - $cpentry[11] = 'first'; - } - $radiusservers = $radiussrvs[$cpentry[11]]; - - captiveportal_disconnect($cpentry, $radiusservers, $term_cause); - captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], $logoutReason); - } - unset($cpdb); + /* reinit ipfw rules */ + captiveportal_init_rules(true); + unlock($cpdblck); unlock($rcprunelock); } |