2021-06-16 12:26:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
|
|
|
|
use Illuminate\Console\Command;
|
2024-11-02 12:30:42 +00:00
|
|
|
use Illuminate\Support\Facades\Config;
|
2021-06-16 12:26:08 +00:00
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
2023-04-22 11:30:30 +00:00
|
|
|
use App\Classes\Protocol\{Binkp,DNS,EMSI};
|
2024-06-01 02:55:27 +00:00
|
|
|
use App\Classes\Sock\Exception\SocketException;
|
|
|
|
use App\Classes\Sock\SocketServer;
|
2021-06-16 12:26:08 +00:00
|
|
|
|
2022-06-26 14:14:36 +00:00
|
|
|
class ServerStart extends Command
|
2021-06-16 12:26:08 +00:00
|
|
|
{
|
2021-08-15 14:41:43 +00:00
|
|
|
private const LOGKEY = 'CSS';
|
|
|
|
|
2021-06-16 12:26:08 +00:00
|
|
|
/**
|
|
|
|
* The name and signature of the console command.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $signature = 'server:start';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The console command description.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $description = 'Start Server';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute the console command.
|
|
|
|
*
|
2024-05-27 05:08:39 +00:00
|
|
|
* @return int
|
2023-07-31 09:14:27 +00:00
|
|
|
* @throws SocketException
|
2021-06-16 12:26:08 +00:00
|
|
|
*/
|
2024-05-27 05:08:39 +00:00
|
|
|
public function handle(): int
|
2021-06-16 12:26:08 +00:00
|
|
|
{
|
2021-08-22 06:55:39 +00:00
|
|
|
Log::info(sprintf('%s:+ Server Starting (%d)',self::LOGKEY,getmypid()));
|
2024-11-02 12:30:42 +00:00
|
|
|
|
|
|
|
if (! our_address()->count())
|
|
|
|
throw new \Exception('We dont have any ACTIVE FTN addresses assigned');
|
|
|
|
|
|
|
|
$o = Config::get('setup');
|
2021-06-24 10:16:37 +00:00
|
|
|
|
2021-08-14 04:10:29 +00:00
|
|
|
$start = collect();
|
2021-06-16 12:26:08 +00:00
|
|
|
|
2023-07-06 01:34:42 +00:00
|
|
|
if ($o->binkp_active)
|
2021-08-14 04:10:29 +00:00
|
|
|
$start->put('binkp',[
|
2023-07-02 13:40:08 +00:00
|
|
|
'address'=>$o->binkp_bind,
|
|
|
|
'port'=>$o->binkp_port,
|
2023-04-22 11:30:30 +00:00
|
|
|
'proto'=>SOCK_STREAM,
|
2024-11-08 21:58:09 +00:00
|
|
|
'class'=>new Binkp($o),
|
2021-08-14 04:10:29 +00:00
|
|
|
]);
|
|
|
|
|
2023-07-06 01:34:42 +00:00
|
|
|
if ($o->emsi_active)
|
2021-08-14 04:10:29 +00:00
|
|
|
$start->put('emsi',[
|
2023-07-31 09:14:27 +00:00
|
|
|
'address'=>$o->emsi_bind,
|
|
|
|
'port'=>$o->emsi_port,
|
2023-04-22 11:30:30 +00:00
|
|
|
'proto'=>SOCK_STREAM,
|
2024-11-08 21:58:09 +00:00
|
|
|
'class'=>new EMSI($o),
|
2021-08-14 04:10:29 +00:00
|
|
|
]);
|
2021-06-16 12:26:08 +00:00
|
|
|
|
2023-07-06 01:34:42 +00:00
|
|
|
if ($o->dns_active)
|
2023-04-22 11:30:30 +00:00
|
|
|
$start->put('dns',[
|
2023-07-31 09:14:27 +00:00
|
|
|
'address'=>$o->dns_bind,
|
|
|
|
'port'=>$o->dns_port,
|
2023-04-22 11:30:30 +00:00
|
|
|
'proto'=>SOCK_DGRAM,
|
2024-11-08 21:58:09 +00:00
|
|
|
'class'=>new DNS($o),
|
2023-04-22 11:30:30 +00:00
|
|
|
]);
|
|
|
|
|
2021-06-16 12:26:08 +00:00
|
|
|
$children = collect();
|
|
|
|
|
2023-07-14 10:03:09 +00:00
|
|
|
Log::debug(sprintf('%s:# Servers [%d]',self::LOGKEY,$start->count()));
|
2021-08-14 04:10:29 +00:00
|
|
|
|
|
|
|
if (! $start->count()) {
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::alert(sprintf('%s:! No servers configured to start',self::LOGKEY));
|
2023-07-14 10:03:09 +00:00
|
|
|
|
2024-05-27 05:08:39 +00:00
|
|
|
return self::FAILURE;
|
2021-08-14 04:10:29 +00:00
|
|
|
}
|
|
|
|
|
2021-07-19 14:23:41 +00:00
|
|
|
pcntl_signal(SIGCHLD,SIG_IGN);
|
2021-06-16 12:26:08 +00:00
|
|
|
|
2021-08-15 14:41:43 +00:00
|
|
|
foreach ($start as $item => $config) {
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::debug(sprintf('%s:- Starting [%s] (%d)',self::LOGKEY,$item,getmypid()));
|
2021-06-16 12:26:08 +00:00
|
|
|
|
|
|
|
$pid = pcntl_fork();
|
|
|
|
|
2023-06-27 07:39:11 +00:00
|
|
|
if ($pid === -1)
|
2021-06-16 12:26:08 +00:00
|
|
|
die('could not fork');
|
|
|
|
|
|
|
|
// We are the child
|
|
|
|
if (! $pid) {
|
2021-08-15 14:41:43 +00:00
|
|
|
Log::withContext(['pid'=>getmypid()]);
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::info(sprintf('%s:= Started [%s]',self::LOGKEY,$item));
|
2021-06-16 12:26:08 +00:00
|
|
|
|
2023-04-22 11:30:30 +00:00
|
|
|
$server = new SocketServer($config['port'],$config['address'],$config['proto']);
|
2023-07-02 13:40:08 +00:00
|
|
|
$server->handler = [$config['class'],'onConnect'];
|
2021-06-16 12:26:08 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
$server->listen();
|
|
|
|
|
|
|
|
} catch (SocketException $e) {
|
2023-06-27 07:39:11 +00:00
|
|
|
if ($e->getMessage() === 'Can\'t accept connections: "Success"')
|
2021-08-15 14:41:43 +00:00
|
|
|
Log::debug(sprintf('%s:! Server Terminated [%s]',self::LOGKEY,$item));
|
2021-06-16 12:26:08 +00:00
|
|
|
else
|
2021-08-15 14:41:43 +00:00
|
|
|
Log::emergency(sprintf('%s:! Uncaught Message: %s',self::LOGKEY,$e->getMessage()));
|
2021-06-16 12:26:08 +00:00
|
|
|
}
|
|
|
|
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::info(sprintf('%s:= Finished: [%s]',self::LOGKEY,$item));
|
2021-06-16 12:26:08 +00:00
|
|
|
|
|
|
|
// Child finished we need to get out of this loop.
|
2024-05-27 05:08:39 +00:00
|
|
|
return self::SUCCESS;
|
2021-06-16 12:26:08 +00:00
|
|
|
}
|
|
|
|
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::debug(sprintf('%s:- Forked for [%s] (%d)',self::LOGKEY,$item,$pid));
|
2021-06-16 12:26:08 +00:00
|
|
|
$children->put($pid,$item);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for children to exit
|
2021-08-14 04:10:29 +00:00
|
|
|
while ($x=$children->count()) {
|
2021-06-16 12:26:08 +00:00
|
|
|
// Wait for children to finish
|
|
|
|
$exited = pcntl_wait($status);
|
|
|
|
|
2021-08-14 04:10:29 +00:00
|
|
|
if ($exited < 0)
|
|
|
|
abort(500,'Something strange for status: '.serialize($status));
|
|
|
|
|
2023-07-19 00:35:29 +00:00
|
|
|
Log::info(sprintf('%s:= Exited: #%d [%s]',self::LOGKEY,$x,$children->pull($exited)));
|
2021-06-16 12:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Done
|
2021-08-15 14:41:43 +00:00
|
|
|
Log::debug(sprintf('%s:= Finished.',self::LOGKEY));
|
2024-05-27 05:08:39 +00:00
|
|
|
|
|
|
|
return self::SUCCESS;
|
2021-06-16 12:26:08 +00:00
|
|
|
}
|
2023-07-31 09:14:27 +00:00
|
|
|
}
|