Complete rework of packet parsing and packet generation

This commit is contained in:
2024-05-17 22:10:54 +10:00
parent 1650d07d5c
commit 29710c37c2
30 changed files with 1394 additions and 1403 deletions

View File

@@ -15,9 +15,9 @@ use Illuminate\Support\Facades\Storage;
use League\Flysystem\UnableToMoveFile;
use App\Classes\File;
use App\Classes\File\Item;
use App\Classes\FTN\{InvalidPacketException,Packet};
use App\Models\Address;
use App\Classes\FTN\Packet;
use App\Exceptions\InvalidPacketException;
use App\Models\{Domain,Echomail,Netmail};
use App\Notifications\Netmails\PacketPasswordInvalid;
class PacketProcess implements ShouldQueue
@@ -26,22 +26,26 @@ class PacketProcess implements ShouldQueue
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private Item $file;
private Address $ao;
private string $filename;
private Domain $do;
private Carbon $rcvd_time;
private bool $interactive;
private bool $nobot;
public function __construct(Item $file,Address $ao,Carbon $rcvd_time)
public function __construct(string $filename,Domain $do,bool $interactive=FALSE,Carbon $rcvd_time=NULL,bool $nobot=FALSE)
{
$this->file = $file;
$this->ao = $ao;
$this->rcvd_time = $rcvd_time;
$this->filename = $filename;
$this->do = $do;
$this->interactive = $interactive;
$this->rcvd_time = $rcvd_time ?: Carbon::now();
$this->nobot = $nobot;
}
public function __get($key): mixed
{
switch ($key) {
case 'subject':
return $this->file->name;
return $this->filename;
default:
return NULL;
@@ -54,30 +58,47 @@ class PacketProcess implements ShouldQueue
*/
public function handle()
{
Log::info(sprintf('%s:- Processing mail %s [%s]',self::LOGKEY,$this->file->whatType() === Item::IS_PKT ? 'PACKET' : 'ARCHIVE',$this->file->nameas));
Log::info(sprintf('%s:- Processing mail [%s]',self::LOGKEY,$this->filename));
$fs = Storage::disk(config('fido.local_disk'));
// @todo Catch files that we cannot process, eg: ARJ bundles.
try {
$f = new File($this->file->full_name);
$f = new File($fs->path($this->filename));
$processed = FALSE;
foreach ($f as $packet) {
$pkt = Packet::process($packet,Arr::get(stream_get_meta_data($packet),'uri'),$f->itemSize(),$this->ao->zone->domain);
$pkt = Packet::process($packet,Arr::get(stream_get_meta_data($packet),'uri'),$f->itemSize(),$this->do);
// Check the messages are from the uplink
if ($this->ao->system->addresses->search(function($item) use ($pkt) { return $item->id === $pkt->fftn_o->id; }) === FALSE) {
Log::error(sprintf('%s:! Packet [%s] is not from this link? [%d]',self::LOGKEY,$pkt->fftn_o->ftn,$this->ao->system_id));
// Check that the packet is from a system that is defined in the DB
if (! $pkt->fftn) {
Log::error(sprintf('%s:! Packet [%s] is not from a system we know about? [%s]',self::LOGKEY,$this->filename,$pkt->fftn_t));
break;
}
// Check the packet password
if (strtoupper($this->ao->session('pktpass')) !== strtoupper($pkt->password)) {
Log::error(sprintf('%s:! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$this->ao->ftn,$pkt->password));
if (! our_nodes($this->do)->contains($pkt->fftn)) {
Log::error(sprintf('%s:! Packet [%s] is from a system that is not configured with us? [%s] for [%s]',self::LOGKEY,$this->filename,$pkt->fftn_t,$this->do->name));
Notification::route('netmail',$this->ao)->notify(new PacketPasswordInvalid($pkt->password,$this->file->nameas));
// @todo Notification::route('netmail',$pkt->fftn)->notify(new UnexpectedPacketFromYou($this->filename));
// @todo Parse the packet for netmails and process them. We'll only accept netmails to us, and ignore all others
break;
}
// Check the packet is to our address, if not we'll reject it.
if (! our_address($this->do)->contains($pkt->tftn)) {
Log::error(sprintf('%s:! Packet [%s] is not to our address? [%s]',self::LOGKEY,$this->filename,$pkt->tftn));
// @todo Notification::route('netmail',$pkt->fftn)->notify(new UnexpectedPacketToUs($this->filename));
break;
}
// Check the packet password
if (strtoupper($pkt->fftn->session('pktpass')) !== strtoupper($pkt->password)) {
Log::error(sprintf('%s:! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$pkt->fftn->ftn,$pkt->password));
Notification::route('netmail',$pkt->fftn)->notify(new PacketPasswordInvalid($pkt->password,$this->filename));
break;
}
@@ -89,37 +110,34 @@ class PacketProcess implements ShouldQueue
$count = 0;
foreach ($pkt as $msg) {
Log::info(sprintf('%s:- Mail from [%s] to [%s]',self::LOGKEY,$msg->fftn,$msg->tftn));
if ($msg instanceof Netmail)
Log::info(sprintf('%s:- Netmail from [%s] to [%s]',self::LOGKEY,$msg->fftn->ftn,$msg->tftn->ftn));
elseif ($msg instanceof Echomail)
Log::info(sprintf('%s:- Echomail from [%s]',self::LOGKEY,$msg->fftn->ftn));
// @todo Quick check that the packet should be processed by us.
// @todo validate that the packet's zone is in the domain.
if ($msg->errors) {
Log::error(sprintf('%s:! Message [%s] has [%d] errors, unable to process',self::LOGKEY,$msg->msgid,$msg->errors->errors()->count()));
/*
* // @todo generate exception when echomail for an area that doesnt exist
* // @todo generate exception when echomail for an area sender cannot post to
* // @todo generate exception when echomail for an area sender not subscribed to
* // @todo generate exception when echomail comes from a system not defined here
* // @todo generate exception when echomail comes from a system doesnt exist
*
* // @todo generate exception when netmail to system that doesnt exist (node/point)
* // @todo generate exception when netmail from system that doesnt exist (node/point)
* // @todo generate warning when netmail comes from a system not defined here
*
* // @todo generate exception when packet has wrong password
*/
continue;
}
$msg->set_sender = $pkt->fftn->withoutRelations();
// Record receiving packet and sender
$msg->set_pkt = $f->pktName();
$msg->set_recvtime = $this->rcvd_time;
try {
// Dispatch job.
if ($queue)
MessageProcess::dispatch($msg,$f->pktName(),$this->ao->withoutRelations(),$pkt->fftn_o->withoutRelations(),$this->rcvd_time);
if ($queue || (! $this->interactive))
MessageProcess::dispatch($msg->withoutRelations(),$this->nobot);
else
MessageProcess::dispatchSync($msg,$f->pktName(),$this->ao->withoutRelations(),$pkt->fftn_o->withoutRelations(),$this->rcvd_time);
MessageProcess::dispatchSync($msg->withoutRelations(),$this->nobot);
$count++;
} catch (\Exception $e) {
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
}
$count++;
}
if ($count === $pkt->count())
@@ -127,42 +145,41 @@ class PacketProcess implements ShouldQueue
}
if (! $processed) {
Log::alert(sprintf('%s:- Not deleting packet [%s], it doesnt seem to be processed?',self::LOGKEY,$this->file->nameas));
Log::alert(sprintf('%s:- Not deleting packet [%s], it doesnt seem to be processed?',self::LOGKEY,$this->filename));
} else {
// If we want to keep the packet, we could do that logic here
if (config('fido.packet_keep')) {
$dir = sprintf('%s/%s/%s/%s',config('fido.dir'),($x=Carbon::now())->format('Y'),$x->format('m'),$x->format('d'));
Log::debug(sprintf('%s:- Moving processed packet [%s] to [%s]',self::LOGKEY,$this->file->rel_name,$dir));
Log::debug(sprintf('%s:- Moving processed packet [%s] to [%s]',self::LOGKEY,$this->filename,$dir));
try {
if ($fs->makeDirectory($dir)) {
$fs->move($this->file->rel_name,$x=sprintf('%s/%s',$dir,$this->file->pref_name));
Log::info(sprintf('%s:- Moved processed packet [%s] to [%s]',self::LOGKEY,$this->file->rel_name,$x));
$fs->move($this->filename,$x=sprintf('%s/%s',$dir,$f->itemName()));
Log::info(sprintf('%s:- Moved processed packet [%s] to [%s]',self::LOGKEY,$this->filename,$x));
} else
Log::error(sprintf('%s:! Unable to create dir [%s]',self::LOGKEY,$dir));
} catch (UnableToMoveFile $e) {
Log::error(sprintf('%s:! Unable to move packet [%s] to [%s] (%s)',self::LOGKEY,$this->file->full_name,$dir,$e->getMessage()));
Log::error(sprintf('%s:! Unable to move packet [%s] to [%s] (%s)',self::LOGKEY,$this->filename,$dir,$e->getMessage()));
} catch (\Exception $e) {
Log::error(sprintf('%s:! Failed moving packet [%s] to [%s] (%s)',self::LOGKEY,$this->file->full_name,$dir,$e->getMessage()));
Log::error(sprintf('%s:! Failed moving packet [%s] to [%s] (%s)',self::LOGKEY,$this->filename,$dir,$e->getMessage()));
}
} else {
Log::debug(sprintf('%s:- Deleting processed packet [%s]',self::LOGKEY,$this->file->full_name));
Log::debug(sprintf('%s:- Deleting processed packet [%s]',self::LOGKEY,$this->filename));
// @todo Change this to use Storage::disk()
unlink($this->file->full_name);
$fs->delete($this->filename);
}
}
} catch (InvalidPacketException $e) {
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an InvalidPacketException',self::LOGKEY,$this->file->nameas),['e'=>$e->getMessage()]);
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an InvalidPacketException',self::LOGKEY,$this->filename),['e'=>$e->getMessage()]);
} catch (\Exception $e) {
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an uncaught exception',self::LOGKEY,$this->file->nameas),['e'=>$e->getMessage()]);
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an uncaught exception',self::LOGKEY,$this->filename),['e'=>$e->getMessage(),'l'=>$e->getLine(),'f'=>$e->getFile()]);
}
}
}