2021-06-29 10:43:29 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Classes\FTN;
|
|
|
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
use Illuminate\Support\Arr;
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
2023-09-20 10:29:23 +00:00
|
|
|
use Illuminate\Support\Facades\Notification;
|
2021-06-29 10:43:29 +00:00
|
|
|
use Symfony\Component\HttpFoundation\File\File;
|
|
|
|
|
|
|
|
use App\Classes\FTN as FTNBase;
|
2023-09-20 10:29:23 +00:00
|
|
|
use App\Models\{Address,Domain,Software,System,Zone};
|
|
|
|
use App\Notifications\Netmails\EchomailBadAddress;
|
2021-06-29 10:43:29 +00:00
|
|
|
|
2023-06-22 07:36:22 +00:00
|
|
|
/**
|
2023-09-14 22:09:42 +00:00
|
|
|
* Represents a Fidonet Packet, that contains an array of messages.
|
|
|
|
*
|
|
|
|
* Thus this object is iterable as an array of Message::class.
|
2023-06-22 07:36:22 +00:00
|
|
|
*/
|
2021-08-24 13:42:03 +00:00
|
|
|
class Packet extends FTNBase implements \Iterator, \Countable
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
|
|
|
private const LOGKEY = 'PKT';
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
protected const PACKED_MSG_LEAD = "\02\00";
|
2023-12-13 12:00:47 +00:00
|
|
|
protected const PACKED_END = "\00\00";
|
2023-06-25 10:45:02 +00:00
|
|
|
|
2023-11-23 12:17:13 +00:00
|
|
|
public const regex = '([[:xdigit:]]{4})(?:-(\d{4,10}))?-(.+)';
|
|
|
|
|
2023-06-26 09:19:42 +00:00
|
|
|
public const PACKET_TYPES = [
|
|
|
|
'2.2' => FTNBase\Packet\FSC45::class,
|
|
|
|
'2+' => FTNBase\Packet\FSC48::class,
|
|
|
|
'2e' => FTNBase\Packet\FSC39::class,
|
|
|
|
'2.0' => FTNBase\Packet\FTS1::class,
|
2021-06-29 10:43:29 +00:00
|
|
|
];
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
protected array $header; // Packet Header
|
|
|
|
protected ?string $name; // Packet name
|
2021-07-15 14:54:23 +00:00
|
|
|
|
|
|
|
public File $file; // Packet filename
|
|
|
|
public Collection $messages; // Messages in the Packet
|
2021-08-13 13:46:48 +00:00
|
|
|
public Collection $errors; // Messages that fail validation
|
2023-09-14 22:09:42 +00:00
|
|
|
protected int $index; // Our array index
|
2021-08-24 13:42:03 +00:00
|
|
|
|
|
|
|
/**
|
2023-06-25 10:45:02 +00:00
|
|
|
* @param string|null $header
|
|
|
|
* @throws \Exception
|
2021-08-24 13:42:03 +00:00
|
|
|
*/
|
2023-06-25 10:45:02 +00:00
|
|
|
public function __construct(string $header=NULL)
|
2021-08-24 13:42:03 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
$this->messages = collect();
|
|
|
|
$this->errors = collect();
|
|
|
|
$this->domain = NULL;
|
|
|
|
$this->name = NULL;
|
2021-08-24 13:42:03 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
if ($header)
|
|
|
|
$this->header = unpack(self::unpackheader(static::HEADER),$header);
|
2021-08-24 13:42:03 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/**
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public function __get($key)
|
2021-08-24 13:42:03 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
switch ($key) {
|
|
|
|
// From Addresses
|
|
|
|
case 'fz': return Arr::get($this->header,'ozone');
|
|
|
|
case 'fn': return Arr::get($this->header,'onet');
|
|
|
|
case 'ff': return Arr::get($this->header,'onode');
|
|
|
|
case 'fp': return Arr::get($this->header,'opoint');
|
|
|
|
case 'fd': return rtrim(Arr::get($this->header,'odomain',"\x00"));
|
2021-08-24 13:42:03 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
// To Addresses
|
|
|
|
case 'tz': return Arr::get($this->header,'dzone');
|
|
|
|
case 'tn': return Arr::get($this->header,'dnet');
|
|
|
|
case 'tf': return Arr::get($this->header,'dnode');
|
|
|
|
case 'tp': return Arr::get($this->header,'dpoint');
|
|
|
|
case 'td': return rtrim(Arr::get($this->header,'ddomain',"\x00"));
|
|
|
|
|
|
|
|
case 'date':
|
|
|
|
return Carbon::create(
|
|
|
|
Arr::get($this->header,'y'),
|
|
|
|
Arr::get($this->header,'m')+1,
|
|
|
|
Arr::get($this->header,'d'),
|
|
|
|
Arr::get($this->header,'H'),
|
|
|
|
Arr::get($this->header,'M'),
|
|
|
|
Arr::get($this->header,'S')
|
|
|
|
);
|
|
|
|
|
|
|
|
case 'password':
|
|
|
|
return rtrim(Arr::get($this->header,$key),"\x00");
|
|
|
|
|
|
|
|
case 'fftn':
|
|
|
|
case 'fftn_o':
|
|
|
|
case 'tftn':
|
|
|
|
case 'tftn_o':
|
|
|
|
return parent::__get($key);
|
|
|
|
|
|
|
|
case 'software':
|
|
|
|
$code = Arr::get($this->header,'prodcode-hi')<<8|Arr::get($this->header,'prodcode-lo');
|
|
|
|
Software::unguard();
|
|
|
|
$o = Software::singleOrNew(['code'=>$code,'type'=>Software::SOFTWARE_TOSSER]);
|
|
|
|
Software::reguard();
|
|
|
|
|
|
|
|
return $o;
|
|
|
|
|
|
|
|
case 'software_ver':
|
|
|
|
return sprintf('%d.%d',Arr::get($this->header,'prodrev-maj'),Arr::get($this->header,'prodrev-min'));
|
|
|
|
|
|
|
|
case 'capability':
|
|
|
|
// This needs to be defined in child classes, since not all children have it
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// Packet Type
|
|
|
|
case 'type':
|
|
|
|
return static::TYPE;
|
|
|
|
|
|
|
|
// Packet name:
|
|
|
|
case 'name':
|
|
|
|
return $this->{$key} ?: sprintf('%08x',timew());
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new \Exception('Unknown key: '.$key);
|
|
|
|
}
|
2021-08-24 13:42:03 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/**
|
|
|
|
* Return the packet
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public function __toString(): string
|
2021-08-24 13:42:03 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
$return = $this->header();
|
|
|
|
|
|
|
|
foreach ($this->messages as $o) {
|
|
|
|
if ($o->packed)
|
|
|
|
$return .= self::PACKED_MSG_LEAD.$o;
|
|
|
|
}
|
|
|
|
|
|
|
|
$return .= "\00\00";
|
|
|
|
|
|
|
|
return $return;
|
2021-08-24 13:42:03 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/* STATIC */
|
|
|
|
|
|
|
|
/**
|
2023-11-15 11:12:09 +00:00
|
|
|
* Size of the packet header
|
2023-06-25 10:45:02 +00:00
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public static function header_len(): int
|
2021-08-24 13:42:03 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
return collect(static::HEADER)->sum(function($item) { return Arr::get($item,2); });
|
2021-08-24 13:42:03 +00:00
|
|
|
}
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2022-01-20 06:54:02 +00:00
|
|
|
/**
|
2023-06-25 10:45:02 +00:00
|
|
|
* This function is intended to be implemented in child classes to test if the packet
|
|
|
|
* is defined by the child object
|
|
|
|
*
|
|
|
|
* @see self::PACKET_TYPES
|
|
|
|
* @param string $header
|
|
|
|
* @return bool
|
2022-01-20 06:54:02 +00:00
|
|
|
*/
|
2023-06-25 10:45:02 +00:00
|
|
|
public static function is_type(string $header): bool
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
return FALSE;
|
2021-07-15 14:54:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-11-13 13:29:55 +00:00
|
|
|
* Process a packet file
|
2021-07-15 14:54:23 +00:00
|
|
|
*
|
2023-12-13 12:00:47 +00:00
|
|
|
* @param mixed $f File handler returning packet data
|
2022-11-13 13:29:55 +00:00
|
|
|
* @param string $name
|
|
|
|
* @param int $size
|
2023-09-20 10:29:23 +00:00
|
|
|
* @param Domain|null $domain
|
2021-07-15 14:54:23 +00:00
|
|
|
* @return Packet
|
|
|
|
* @throws InvalidPacketException
|
|
|
|
*/
|
2023-09-20 10:29:23 +00:00
|
|
|
public static function process(mixed $f,string $name,int $size,Domain $domain=NULL): self
|
2021-07-15 14:54:23 +00:00
|
|
|
{
|
2022-11-13 13:29:55 +00:00
|
|
|
Log::debug(sprintf('%s:+ Opening Packet [%s] with size [%d]',self::LOGKEY,$name,$size));
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
$o = FALSE;
|
|
|
|
$header = '';
|
2022-11-13 13:29:55 +00:00
|
|
|
$read_ptr = 0;
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
// Determine the type of packet
|
|
|
|
foreach (self::PACKET_TYPES as $type) {
|
|
|
|
$header_len = $type::header_len();
|
|
|
|
|
|
|
|
// PKT Header
|
|
|
|
if ($read_ptr < $header_len) {
|
|
|
|
$header .= fread($f,$header_len-$read_ptr);
|
|
|
|
$read_ptr = ftell($f);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Could not read header
|
|
|
|
if (strlen($header) !== $header_len)
|
|
|
|
throw new InvalidPacketException(sprintf('Length of header [%d] too short',strlen($header)));
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
if ($type::is_type($header)) {
|
|
|
|
$o = new $type($header);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
if (! $o)
|
|
|
|
throw new InvalidPacketException('Cannot determine type of packet.');
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2022-11-13 13:29:55 +00:00
|
|
|
$o->name = $name;
|
2021-07-15 14:54:23 +00:00
|
|
|
|
|
|
|
$x = fread($f,2);
|
2023-12-13 12:00:47 +00:00
|
|
|
if (strlen($x) === 2) {
|
|
|
|
// End of Packet?
|
|
|
|
if ($x === "\00\00")
|
|
|
|
return $o;
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-12-13 12:00:47 +00:00
|
|
|
// Messages start with self::PACKED_MSG_LEAD
|
|
|
|
elseif ($x !== self::PACKED_MSG_LEAD)
|
|
|
|
throw new InvalidPacketException('Not a valid packet: '.bin2hex($x));
|
2021-06-29 10:43:29 +00:00
|
|
|
|
2021-07-15 14:54:23 +00:00
|
|
|
// No message attached
|
2023-12-13 12:00:47 +00:00
|
|
|
} else
|
|
|
|
throw new InvalidPacketException('Not a valid packet, not EOP or SOM'.bin2hex($x));
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-09-20 10:29:23 +00:00
|
|
|
// Work out the packet zone
|
|
|
|
if ($o->fz && ($o->fd || $domain)) {
|
|
|
|
$o->zone = Zone::select('zones.*')
|
|
|
|
->join('domains',['domains.id'=>'zones.domain_id'])
|
|
|
|
->where('zone_id',$o->fz)
|
|
|
|
->where('name',$o->fd ?: $domain->name)
|
|
|
|
->single();
|
|
|
|
|
|
|
|
// We need not knowing the domain, we use the default zone
|
|
|
|
} else {
|
|
|
|
$o->zone = Zone::where('zone_id',$o->fz)
|
|
|
|
->where('default',TRUE)
|
|
|
|
->single();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If zone is not set, then we need to use a default zone - the messages may not be from this zone.
|
|
|
|
if (! $o->zone) {
|
|
|
|
Log::alert(sprintf('%s:! We couldnt work out the packet zone, so we have fallen back to the default for [%d]',self::LOGKEY,$o->fz));
|
2021-11-24 11:34:40 +00:00
|
|
|
|
2023-09-20 10:29:23 +00:00
|
|
|
$o->zone = Zone::where('zone_id',$o->fz)
|
|
|
|
->where('default',TRUE)
|
|
|
|
->singleOrFail();
|
|
|
|
}
|
2021-08-29 13:58:12 +00:00
|
|
|
|
2023-12-07 09:19:48 +00:00
|
|
|
$message = ''; // Current message we are building
|
2023-12-13 12:00:47 +00:00
|
|
|
$msgbuf = '';
|
|
|
|
$leader = Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD);
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-12-07 09:19:48 +00:00
|
|
|
// We loop through reading from the buffer, to find our end of message tag
|
2023-12-13 12:00:47 +00:00
|
|
|
while ((! feof($f) && ($readbuf=fread($f,$leader)))) {
|
|
|
|
$read_ptr = ftell($f);
|
|
|
|
$msgbuf .= $readbuf;
|
|
|
|
|
|
|
|
// See if we have our EOM/EOP marker
|
|
|
|
if ((($end=strpos($msgbuf,"\x00".self::PACKED_MSG_LEAD,$leader)) !== FALSE)
|
|
|
|
|| (($end=strpos($msgbuf,"\x00".self::PACKED_END,$leader)) !== FALSE))
|
|
|
|
{
|
|
|
|
// Parse our message
|
|
|
|
$o->parseMessage(substr($msgbuf,0,$end));
|
|
|
|
|
|
|
|
$msgbuf = substr($msgbuf,$end+3);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// If we have more to read
|
|
|
|
} elseif ($read_ptr < $size) {
|
|
|
|
continue;
|
2021-08-26 12:01:16 +00:00
|
|
|
}
|
|
|
|
|
2023-12-13 12:00:47 +00:00
|
|
|
// If we get here
|
|
|
|
throw new InvalidPacketException(sprintf('Cannot determine END of message/packet: %s|%s',get_class($o),hex_dump($message)));;
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
2021-07-15 14:54:23 +00:00
|
|
|
|
2023-12-13 12:00:47 +00:00
|
|
|
if ($msgbuf)
|
|
|
|
throw new InvalidPacketException(sprintf('Unprocessed data in packet: %s|%s',get_class($o),hex_dump($msgbuf)));
|
2021-07-30 14:35:52 +00:00
|
|
|
|
2021-07-15 14:54:23 +00:00
|
|
|
return $o;
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-06-25 10:45:02 +00:00
|
|
|
* Location of the version
|
|
|
|
*
|
|
|
|
* @return int
|
2021-06-29 10:43:29 +00:00
|
|
|
*/
|
2023-06-25 10:45:02 +00:00
|
|
|
public static function version_offset(): int
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
return Arr::get(collect(static::HEADER)->get('type'),0);
|
|
|
|
}
|
2021-07-18 12:10:21 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public static function version_offset_len(): int
|
|
|
|
{
|
|
|
|
return Arr::get(collect(static::HEADER)->get('type'),2);
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/* INTERFACE */
|
|
|
|
|
2021-07-15 14:54:23 +00:00
|
|
|
/**
|
2023-06-25 10:45:02 +00:00
|
|
|
* Number of messages in this packet
|
2021-07-15 14:54:23 +00:00
|
|
|
*/
|
2023-06-25 10:45:02 +00:00
|
|
|
public function count(): int
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
return $this->messages->count();
|
|
|
|
}
|
2021-06-29 10:43:29 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public function current(): Message
|
|
|
|
{
|
2023-09-14 22:09:42 +00:00
|
|
|
return $this->messages->get($this->index);
|
2023-06-25 10:45:02 +00:00
|
|
|
}
|
2021-06-29 10:43:29 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public function key(): mixed
|
|
|
|
{
|
2023-09-14 22:09:42 +00:00
|
|
|
return $this->index;
|
2023-06-25 10:45:02 +00:00
|
|
|
}
|
2021-09-08 12:07:00 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public function next(): void
|
|
|
|
{
|
|
|
|
$this->index++;
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public function rewind(): void
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-06-25 10:45:02 +00:00
|
|
|
$this->index = 0;
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
public function valid(): bool
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-09-14 22:09:42 +00:00
|
|
|
return (! is_null($this->key())) && $this->messages->has($this->key());
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/* METHODS */
|
|
|
|
|
2021-06-29 10:43:29 +00:00
|
|
|
/**
|
2021-07-15 14:54:23 +00:00
|
|
|
* When creating a new packet, set the header.
|
2021-06-29 10:43:29 +00:00
|
|
|
*
|
2022-01-20 06:54:02 +00:00
|
|
|
* @param Address $oo
|
2021-07-17 05:48:07 +00:00
|
|
|
* @param Address $o
|
2023-07-23 07:27:52 +00:00
|
|
|
* @param string|null $passwd Override the password used in the packet
|
2021-06-29 10:43:29 +00:00
|
|
|
*/
|
2023-07-23 07:27:52 +00:00
|
|
|
public function addressHeader(Address $oo,Address $o,string $passwd=NULL): void
|
2021-06-29 10:43:29 +00:00
|
|
|
{
|
2023-07-11 11:34:47 +00:00
|
|
|
Log::debug(sprintf('%s:+ Creating packet for [%s]',self::LOGKEY,$o->ftn));
|
2023-06-25 10:45:02 +00:00
|
|
|
|
2021-07-15 14:54:23 +00:00
|
|
|
$date = Carbon::now();
|
|
|
|
|
|
|
|
// Create Header
|
|
|
|
$this->header = [
|
2023-06-25 10:45:02 +00:00
|
|
|
'ozone' => $oo->zone->zone_id, // Orig Zone
|
|
|
|
'dzone' => $o->zone->zone_id, // Dest Zone
|
|
|
|
'onet' => $oo->host_id ?: $oo->region_id, // Orig Net
|
|
|
|
'dnet' => $o->host_id ?: $o->region_id, // Dest Net
|
|
|
|
'onode' => $oo->node_id, // Orig Node
|
|
|
|
'dnode' => $o->node_id, // Dest Node
|
|
|
|
'opoint' => $oo->point_id, // Orig Point
|
|
|
|
'dpoint' => $o->point_id, // Dest Point
|
|
|
|
'odomain' => $oo->zone->domain->name, // Orig Domain
|
|
|
|
'ddomain' => $o->zone->domain->name, // Dest Domain
|
2021-08-20 14:33:41 +00:00
|
|
|
'y' => $date->format('Y'), // Year
|
|
|
|
'm' => $date->format('m')-1, // Month
|
|
|
|
'd' => $date->format('d'), // Day
|
|
|
|
'H' => $date->format('H'), // Hour
|
|
|
|
'M' => $date->format('i'), // Minute
|
|
|
|
'S' => $date->format('s'), // Second
|
2023-11-24 22:47:58 +00:00
|
|
|
'password' => strtoupper((! is_null($passwd)) ? $passwd : $o->session('pktpass')), // Packet Password
|
2021-07-15 14:54:23 +00:00
|
|
|
];
|
|
|
|
}
|
2021-06-29 10:43:29 +00:00
|
|
|
|
2023-06-25 10:45:02 +00:00
|
|
|
/**
|
2023-07-14 10:03:09 +00:00
|
|
|
* Add a message to this packet
|
2023-06-25 10:45:02 +00:00
|
|
|
*
|
|
|
|
* @param Message $o
|
|
|
|
*/
|
|
|
|
public function addMail(Message $o): void
|
|
|
|
{
|
|
|
|
$this->messages->push($o);
|
|
|
|
}
|
|
|
|
|
2021-07-15 14:54:23 +00:00
|
|
|
/**
|
|
|
|
* Parse a message in a mail packet
|
|
|
|
*
|
|
|
|
* @param string $message
|
2021-09-11 13:32:10 +00:00
|
|
|
* @throws InvalidPacketException|\Exception
|
2021-07-15 14:54:23 +00:00
|
|
|
*/
|
2021-08-29 13:58:12 +00:00
|
|
|
private function parseMessage(string $message): void
|
2021-07-15 14:54:23 +00:00
|
|
|
{
|
2023-09-20 10:29:23 +00:00
|
|
|
Log::info(sprintf('%s:+ Processing packet message [%d] bytes',self::LOGKEY,strlen($message)));
|
2021-12-29 02:44:27 +00:00
|
|
|
|
2021-08-29 13:58:12 +00:00
|
|
|
$msg = Message::parseMessage($message,$this->zone);
|
2021-07-19 14:26:12 +00:00
|
|
|
|
2023-09-20 10:29:23 +00:00
|
|
|
// If the message from domain is different to the packet address domain, we'll skip this message
|
|
|
|
|
2021-07-19 14:26:12 +00:00
|
|
|
// If the message is invalid, we'll ignore it
|
2021-09-11 13:32:10 +00:00
|
|
|
if ($msg->errors) {
|
2022-01-15 02:06:15 +00:00
|
|
|
Log::info(sprintf('%s:- Message [%s] has errors',self::LOGKEY,$msg->msgid));
|
2021-12-29 02:44:27 +00:00
|
|
|
|
2023-09-20 10:29:23 +00:00
|
|
|
// If the messages is not for the right zone, we'll ignore it
|
|
|
|
if ($msg->errors->messages()->has('invalid-zone')) {
|
|
|
|
Log::alert(sprintf('%s:! Message is from an invalid zone [%s], packet is from [%s] - ignoring it',self::LOGKEY,$msg->fftn,$msg->zone->domain->name));
|
|
|
|
|
|
|
|
if (! $msg->rescanned->count())
|
|
|
|
Notification::route('netmail',$this->fftn_o)->notify(new EchomailBadAddress($msg));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the to address doenst exist, we'll create a new entry
|
2022-12-03 05:00:38 +00:00
|
|
|
if ($msg->errors->messages()->has('to') && $msg->tzone) {
|
2022-11-06 03:40:03 +00:00
|
|
|
try {
|
2023-01-01 03:30:15 +00:00
|
|
|
// @todo Need to work out the correct region for the host_id
|
2022-11-06 03:40:03 +00:00
|
|
|
Address::unguard();
|
|
|
|
$ao = Address::firstOrNew([
|
|
|
|
'zone_id' => $msg->tzone->id,
|
2023-07-06 03:55:54 +00:00
|
|
|
//'region_id' => 0,
|
2022-11-06 03:40:03 +00:00
|
|
|
'host_id' => $msg->tn,
|
|
|
|
'node_id' => $msg->tf,
|
|
|
|
'point_id' => $msg->tp,
|
2023-01-01 14:05:44 +00:00
|
|
|
'active' => TRUE,
|
2022-11-06 03:40:03 +00:00
|
|
|
]);
|
|
|
|
Address::reguard();
|
|
|
|
|
2023-07-06 03:55:54 +00:00
|
|
|
if (is_null($ao->region_id))
|
|
|
|
$ao->region_id = $ao->host_id;
|
|
|
|
|
2022-11-06 03:40:03 +00:00
|
|
|
} catch (\Exception $e) {
|
2022-11-11 11:57:40 +00:00
|
|
|
Log::error(sprintf('%s:! Error finding/creating TO address [%s] for message',self::LOGKEY,$msg->tboss),['error'=>$e->getMessage()]);
|
2022-11-06 03:40:03 +00:00
|
|
|
$this->errors->push($msg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$ao->role = Address::NODE_UNKNOWN;
|
|
|
|
|
2023-09-15 12:57:32 +00:00
|
|
|
$so = System::createUnknownSystem();
|
2022-11-06 03:40:03 +00:00
|
|
|
|
|
|
|
$so->addresses()->save($ao);
|
|
|
|
|
2023-09-19 00:21:17 +00:00
|
|
|
Log::alert(sprintf('%s:- To FTN is not defined, creating new entry for [%s] (%d)',self::LOGKEY,$msg->tboss,$ao->id));
|
2022-11-06 03:40:03 +00:00
|
|
|
}
|
|
|
|
|
2023-09-20 10:29:23 +00:00
|
|
|
// If the from address doenst exist, we'll create a new entry
|
2022-12-03 05:00:38 +00:00
|
|
|
if ($msg->errors->messages()->has('from') && $msg->tzone) {
|
2021-09-12 12:09:45 +00:00
|
|
|
try {
|
2023-01-01 03:30:15 +00:00
|
|
|
// @todo Need to work out the correct region for the host_id
|
2021-09-12 12:09:45 +00:00
|
|
|
Address::unguard();
|
|
|
|
$ao = Address::firstOrNew([
|
|
|
|
'zone_id' => $msg->fzone->id,
|
2023-07-06 03:55:54 +00:00
|
|
|
//'region_id' => 0,
|
2021-09-12 12:09:45 +00:00
|
|
|
'host_id' => $msg->fn,
|
|
|
|
'node_id' => $msg->ff,
|
|
|
|
'point_id' => $msg->fp,
|
2023-01-01 14:05:44 +00:00
|
|
|
'active'=> TRUE,
|
2021-09-12 12:09:45 +00:00
|
|
|
]);
|
|
|
|
Address::reguard();
|
|
|
|
|
2023-07-06 03:55:54 +00:00
|
|
|
if (is_null($ao->region_id))
|
|
|
|
$ao->region_id = $ao->host_id;
|
|
|
|
|
2021-09-12 12:09:45 +00:00
|
|
|
} catch (\Exception $e) {
|
2022-11-11 11:57:40 +00:00
|
|
|
Log::error(sprintf('%s:! Error finding/creating FROM address [%s] for message',self::LOGKEY,$msg->fboss),['error'=>$e->getMessage()]);
|
2021-09-11 13:32:10 +00:00
|
|
|
$this->errors->push($msg);
|
|
|
|
return;
|
|
|
|
}
|
2021-08-24 13:42:03 +00:00
|
|
|
|
2022-01-24 11:56:13 +00:00
|
|
|
$ao->role = Address::NODE_UNKNOWN;
|
2021-09-12 12:09:45 +00:00
|
|
|
|
2023-09-15 12:57:32 +00:00
|
|
|
$so = System::createUnknownSystem();
|
2021-09-11 13:32:10 +00:00
|
|
|
|
|
|
|
$so->addresses()->save($ao);
|
|
|
|
|
2023-09-19 00:21:17 +00:00
|
|
|
Log::alert(sprintf('%s:- From FTN is not defined, creating new entry for [%s] (%d)',self::LOGKEY,$msg->fboss,$ao->id));
|
2022-11-06 03:40:03 +00:00
|
|
|
}
|
2021-09-12 12:09:45 +00:00
|
|
|
|
2022-11-06 03:40:03 +00:00
|
|
|
if ($msg->errors->messages()->has('user_from') || $msg->errors->messages()->has('user_to')) {
|
2021-09-11 13:32:10 +00:00
|
|
|
Log::error(sprintf('%s:! Skipping message [%s] due to errors (%s)...',self::LOGKEY,$msg->msgid,join(',',$msg->errors->messages()->keys())));
|
|
|
|
$this->errors->push($msg);
|
|
|
|
return;
|
2021-08-24 13:42:03 +00:00
|
|
|
}
|
2021-07-19 14:26:12 +00:00
|
|
|
}
|
2021-09-11 13:32:10 +00:00
|
|
|
|
2023-09-14 22:09:42 +00:00
|
|
|
$this->messages->push($msg);
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|
2023-12-13 12:00:47 +00:00
|
|
|
|
|
|
|
public function pluck(string $key): Collection
|
|
|
|
{
|
|
|
|
return $this->messages->pluck($key);
|
|
|
|
}
|
2021-06-29 10:43:29 +00:00
|
|
|
}
|