Compare commits

...

3 Commits

Author SHA1 Message Date
Deon George 001618d719 Move zone:check to debug namespace, add address:check command
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 35s Details
Create Docker Image / Build Docker Image (arm64) (push) Successful in 1m37s Details
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s Details
2024-04-21 22:10:12 +10:00
Deon George bba6f93fbc Code improvement to our_address(), reducing arguments 2024-04-21 21:40:55 +10:00
Deon George 1c270025cf Move determination of system packet to System::class 2024-04-21 20:40:19 +10:00
12 changed files with 123 additions and 33 deletions

View File

@ -70,7 +70,7 @@ class HubStats extends Dynamic
$header = "| %-12s | %4d | %3d | %3d | %16s | %5s | %5s |\r\n";
$output = sprintf("Hub Status for [%s] as at [%s]\r\n",our_address($this->ao->zone->domain,$this->ao)->ftn,$date);
$output = sprintf("Hub Status for [%s] as at [%s]\r\n",our_address($this->ao)->ftn,$date);
$output .= "\r";
$output .= "+--------------+------+-----+-----+------------------+-------+-------+\r\n";
$output .= "| FTN | ECHO | NET |FILES| LAST SESSION | MODE |AUTOHLD|\r\n";

View File

@ -90,7 +90,7 @@ class Tic extends FTNBase
if (! $this->to)
throw new \Exception('No to address defined');
$sysaddress = our_address($this->to->zone->domain,$this->to);
$sysaddress = our_address($this->to);
$result = collect();

View File

@ -0,0 +1,32 @@
<?php
namespace App\Console\Commands\Debug;
use Illuminate\Console\Command;
use App\Models\Address;
class AddressCheck extends Command
{
protected $signature = 'debug:address:check'
.' {ftn : FTN}';
protected $description = 'Check the addresses we use for a node';
public function handle()
{
$o = Address::findFTN($this->argument('ftn'));
if (! $o) {
$this->error(sprintf('Address: %s doesnt exist?',$this->argument('ftn')));
return Command::FAILURE;
}
$this->info(sprintf('Address: %s',$o->ftn));
$this->info(sprintf('Uplink: %s',$o->parent()?->ftn));
$this->info(sprintf('Our Address: %s',our_address($o)?->ftn));
$this->info(sprintf('Domain Addresses: %s',our_address($o->zone->domain)->pluck('ftn4d')->join(',')));
return Command::SUCCESS;
}
}

View File

@ -1,14 +1,14 @@
<?php
namespace App\Console\Commands;
namespace App\Console\Commands\Debug;
use App\Models\{Domain};
use App\Models\Address;
use Illuminate\Console\Command;
use App\Models\{Address,Domain};
class ZoneCheck extends Command
{
protected $signature = 'zone:check'
protected $signature = 'debug:zone:check'
.' {domain : Domain Name}'
.' {--Z|zone= : Zone}';
@ -25,12 +25,13 @@ class ZoneCheck extends Command
$this->warn('Zone: '.$zo->zone_id);
$this->info(sprintf('- Our address(es): %s',our_address($do)->pluck('ftn4d')->join(',')));
$this->table(['id','ftn','role','parent','region_id','host_id','hub_id','system','notes'],$zo->addresses()->FTNorder()->active()->with(['system'])->get()->transform(function($item) {
$this->table(['id','ftn','role','parent','our_address','region_id','host_id','hub_id','system','notes'],$zo->addresses()->FTNorder()->active()->with(['system'])->get()->transform(function($item) {
return [
'id'=>$item->id,
'ftn'=>$item->ftn4d,
'role'=>$item->role_name,
'parent'=>$item->parent()?->ftn4d,
'parent'=>($x=$item->parent())?->ftn4d,
'our_address'=>$x ? our_address($item->parent())->ftn4d : '',
'region_id'=>$item->region_id,
'host_id'=>$item->host_id,
'hub_id'=>$item->hub_id,

View File

@ -14,14 +14,41 @@ use App\Classes\FTN\{Message,Packet};
use App\Exceptions\InvalidFTNException;
use App\Traits\ScopeActive;
/**
* This represents an FTN AKA.
*
* If an address is active, it belongs to the system. There can only be 1 active FTN (z:h/n.p@d)
* If an address is not active, it belonged to the system at a point in time in the past.
*
* If an address is validated, we know that the system is using the address (we've confirmed that during a session).
* Any mail for that address will be delivered.
*
* If an address is not validated, and the session password matches, validate the address.
* If the session password doesnt match, treat the address as foreign (dont deliver, unless we originate netmail)
*
* Session:
* + address not active
* ++ address validated (shouldnt be the case)
* ++ address not validated
*
* + address active
* ++ address validated (give mail/files)
* ++ address not validated - validate if the password is correct
*
* Mail in (from)
* ++ address not validated, do not process
* ++ address validated, process
*
* Mail out (to)
* ++ address validated, deliver
* ++ address not validated, only deliver netmail if we originate the call
*/
class Address extends Model
{
use ScopeActive,SoftDeletes;
private const LOGKEY = 'MA-';
protected $with = ['zone'];
// http://ftsc.org/docs/frl-1028.002
public const ftn_regex = '(\d+):(\d+)/(\d+)(?:\.(\d+))?(?:@([a-zA-Z0-9\-_~]{0,8}))?';
@ -30,9 +57,9 @@ class Address extends Model
public const NODE_NC = 1<<2; // Host
public const NODE_HC = 1<<3; // Hub
public const NODE_ACTIVE = 1<<4; // Node
public const NODE_PVT = 1<<5; // Pvt
public const NODE_HOLD = 1<<6; // Hold
public const NODE_DOWN = 1<<7; // Down
public const NODE_PVT = 1<<5; // Pvt (we dont have address information) @todo
public const NODE_HOLD = 1<<6; // Hold (user has requested hold, we havent heard from the node for 7 days @todo
public const NODE_DOWN = 1<<7; // Down we havent heard from the node for 30 days @todo
public const NODE_POINT = 1<<8; // Point
public const NODE_UNKNOWN = 1<<15; // Unknown
public const NODE_ALL = 0xFFF; // Mask to catch all nodes
@ -802,7 +829,7 @@ class Address extends Model
public function getPacket(Collection $msgs,string $passwd=NULL): ?Packet
{
$s = Setup::findOrFail(config('app.id'));
$ao = our_address($this->zone->domain,$this);
$ao = our_address($this);
// If we dont match on the address, we cannot pack mail for that system
if (! $ao) {
@ -811,8 +838,7 @@ class Address extends Model
}
// Get packet type
$type = collect(Packet::PACKET_TYPES)->get($this->system->pkt_type ?: config('fido.packet_default'));
$o = new $type;
$o = $ao->system->packet();
$o->addressHeader($ao,$this,$passwd);
// $oo = Netmail/Echomail Model

View File

@ -214,7 +214,7 @@ final class Echomail extends Model implements Packet
{
Log::info(sprintf('%s:+ Bundling [%s]',self::LOGKEY,$this->id));
$sysaddress = our_address($this->fftn->zone->domain,$this->fftn);
$sysaddress = our_address($this->fftn);
if (! $sysaddress)
throw new \Exception(sprintf('%s:! We dont have an address in this network? (%s)',self::LOGKEY,$this->fftn->zone->domain->name));

View File

@ -210,7 +210,7 @@ final class Netmail extends Model implements Packet
// Add our address to the VIA line
$via->push(
sprintf('%s @%s.UTC %s %d.%d/%s %s',
our_address($this->fftn->zone->domain,$this->fftn)->ftn3d,
our_address($this->fftn)->ftn3d,
Carbon::now()->utc()->format('Ymd.His'),
str_replace(' ','_',Setup::PRODUCT_NAME),
Setup::PRODUCT_VERSION_MAJ,

View File

@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use App\Classes\FTN\Packet;
use App\Jobs\AddressPoll;
class System extends Model
@ -249,6 +250,17 @@ class System extends Model
});
}
/**
* Return the packet that this system uses
*
* @return Packet
*/
public function packet(): Packet
{
return new (collect(Packet::PACKET_TYPES)
->get($this->pkt_type ?: config('fido.packet_default')));
}
public function poll(): ?Job
{
return Job::where('queue',AddressPoll::QUEUE)

View File

@ -60,7 +60,7 @@ abstract class Echomails extends Notification //implements ShouldQueue
$o->datetime = Carbon::now();
$o->tzoffset = $o->datetime->utcOffset();
$o->fftn_id = ($x=our_address($mo->fboss_o->zone->domain,$mo->fboss_o))->id;
$o->fftn_id = ($x=our_address($mo->fboss_o))->id;
$o->flags = (Message::FLAG_LOCAL);
$o->tearline = sprintf('%s (%04X)',Setup::PRODUCT_NAME,Setup::PRODUCT_ID);

View File

@ -48,6 +48,7 @@ abstract class Netmails extends Notification //implements ShouldQueue
protected function setupNetmail(object $notifiable): Netmail
{
// @todo Redirect netmails to Hubs or higher to the admin
$ao = $notifiable->routeNotificationFor(static::via);
$o = new Netmail;
@ -57,7 +58,7 @@ abstract class Netmails extends Notification //implements ShouldQueue
$o->datetime = Carbon::now();
$o->tzoffset = $o->datetime->utcOffset();
$o->fftn_id = our_address($ao->zone->domain,$ao)->id;
$o->fftn_id = our_address($ao)->id;
$o->tftn_id = $ao->id;
$o->flags = (Message::FLAG_LOCAL|Message::FLAG_PRIVATE);
$o->cost = 0;

View File

@ -16,7 +16,7 @@ trait MsgID
{
// Only create a MSGID for locally generated content
if ((! $this->exists) && ($this->flags & Message::FLAG_LOCAL) && (is_null(Arr::get($this->attributes,'msgid')))) {
$ftn = our_address($this->fftn->zone->domain,$this->fftn);
$ftn = our_address($this->fftn);
$this->attributes['msgid'] = sprintf('%s %08x',$ftn->ftn4d,timew());
}

View File

@ -3,7 +3,7 @@
use Carbon\Carbon;
use Illuminate\Support\Collection;
use App\Models\{Address,Domain,Setup,Zone};
use App\Models\{Address,Domain,Setup};
/**
* Calculate CCITT-CRC16 checksum
@ -83,13 +83,14 @@ if (! function_exists('hexstr')) {
/**
* Return our addresses.
* If zone provided, limit the list to those within the zone
* If domain provided, limit the list to those within the domain - returning a Collection::class
* If address provided, return our address that would be used for the provided address - return Address::class
*
* @param Domain|NULL $do Limit the addresses for the specific domain
* @param Address|null $ao If address is presented, show the address we use when talking to that address
* @param Domain|Address|null $o - Domain or Address
* @return Collection|Address|NULL
* @throws Exception
*/
function our_address(Domain $do=NULL,Address $ao=NULL): Collection|Address|NULL
function our_address(Domain|Address $o=NULL): Collection|Address|NULL
{
static $so = NULL;
static $our = NULL;
@ -102,15 +103,32 @@ function our_address(Domain $do=NULL,Address $ao=NULL): Collection|Address|NULL
$our = $so->system->akas;
}
$filter = $our;
if ($do)
$filter = $our->filter(function($item) use ($do) { return $item->zone->domain_id === $do->id; })->sortBy('role');
// If we dont have any addresses
if ($our->count() === 0)
return NULL;
// If we are looking for a specific address, and there is only 1 result, return it, otherwise return what we have
if ($ao && config('fido.strict') && ($x=$filter->filter(function($item) use ($ao) { return $item->role <= $ao->role; })->sortBy('role'))->count())
$filter = $x;
// We havent asked for an address/domain, so we'll return them all.
if (is_null($o))
return $our;
return $ao ? $filter->last() : ($do ? $filter : $our);
// We are requesting a list of addresses for a Domain, or a specific Address, and we have more than 1
switch (get_class($o)) {
case Address::class:
$filter = $our->filter(function($item) use ($o) { return $item->zone->domain_id === $o->zone->domain_id; })->sortBy('role');
// If we are looking for a specific address, and there is only 1 result, return it, otherwise return what we have
if (config('fido.strict') && ($x=$filter->filter(function($item) use ($o) { return $item->role <= $o->role; })->sortBy('role'))->count())
$filter = $x;
return $filter->last();
case Domain::class:
return $our->filter(function($item) use ($o) { return $item->zone->domain_id === $o->id; })->sortBy('role');
// We shouldnt get here
default:
throw new Exception('Unhandled class: '.get_class($o));
}
}
/**