Force close port (#6870)

* force close profile sip ports

* create force_close_port function

* force close profile sip ports
This commit is contained in:
frytimo 2024-01-17 12:05:28 -04:00 committed by GitHub
parent 81fbd31524
commit 0b977f044d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 75 additions and 0 deletions

View File

@ -50,6 +50,26 @@
$profile_name = $database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//get the port from sip profile name
$sql = "select sip_profile_setting_value from v_sip_profile_settings ";
$sql .= "where sip_profile_uuid = (select sip_profile_uuid from v_sip_profiles where sip_profile_name = :profile_name limit 1) ";
$sql .= "and sip_profile_setting_name = 'sip-port' ";
$sql .= "and sip_profile_setting_enabled = 'true' ";
$sql .= "limit 1";
$parameters['profile_name'] = $profile;
$profile_port = $database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//get the tls port from sip profile name
$sql = "select sip_profile_setting_value from v_sip_profile_settings ";
$sql .= "where sip_profile_uuid = (select sip_profile_uuid from v_sip_profiles where sip_profile_name = :profile_name limit 1) ";
$sql .= "and sip_profile_setting_name = 'tls-sip-port' ";
$sql .= "and sip_profile_setting_enabled = 'true' ";
$sql .= "limit 1";
$parameters['profile_name'] = $profile;
$profile_tls_port = $database->select($sql, $parameters, 'column');
unset($sql, $parameters);
//validate the gateway
if (!empty($_GET['gateway']) && is_uuid($_GET['gateway'])) {
$gateway_name = $_GET['gateway'];
@ -62,6 +82,9 @@
break;
case "start":
$command = "sofia profile '".$profile_name."' start";
//ensure there are no stuck ports before trying to start the profile
force_close_port($profile_port);
force_close_port($profile_tls_port);
break;
case "stop":
$command = "sofia profile '".$profile_name."' stop";

View File

@ -1082,4 +1082,56 @@ if(!function_exists('win_find_php')) {
}
}
/**
* Forces a port to close using the debugger tool.
* Linux OSes do not have an easy mechanism for closing a port already in use. This uses a debugger tool
* to connect to the running freeswitch process and close the port internally using debug symbols. This
* function requires freeswitch to be compiled with the --enable-debug flag.
* @param string $port
* @return void
*/
function force_close_port(string $port): void {
//ensure we can execute cli tools needed
if (PHP_OS !== 'Linux' || PHP_OS !== 'FreeBSD') {
return;
}
//get the pid of freeswitch
$pid = exec('pidof freeswitch');
//ensure it is numeric before proceeding
if (!is_numeric($pid)) {
return;
}
//get a list of the current connections owned by freeswitch
$connections = "";
exec("lsof -np {$pid} | grep TCP", $connections);
exec("lsof -np {$pid} | grep UDP", $connections);
//iterate over all the current ports
foreach ($connections as $conn) {
//seperate in to fields removing empty ones
$fields = array_values(array_filter(explode(" ", $conn), function ($value) {
if (!empty($value)) return true;
else return false;
}));
//remove letter from id
$id = substr($fields[3], 0, strlen($fields[3]) - 1);
//get the address and port parts
$elements = explode(":", $fields[8]);
//get the port from last element as IPv6 can have more than one ':'
$p = array_pop($elements);
//check for lsof renaming port 5060 to sip
if (!is_numeric($p) && $p == "sip") {
$p = "5060";
}
//check for matching port
if ($p == $port) {
//execute debugger to close the open connection
exec("gdb -p {$pid} -batch 'call close({$id})' -batch 'quit'");
}
}
}
?>