Just optimisations

This commit is contained in:
Deon George
2019-05-20 17:18:18 +10:00
parent 9317f78a3a
commit df849c0cfd
12 changed files with 877 additions and 519 deletions

View File

@@ -2,16 +2,25 @@
namespace App\Classes;
use Illuminate\Support\Arr;
use App\Exceptions\InvalidFidoPacketException;
/**
* Class FTNMessage
* NOTE: FTN Echomail Messages are ZONE agnostic.
*
* @package App\Classes
*/
class FTNMessage extends FTN
{
private $_src = NULL;
private $_dst = NULL;
private $src = NULL; // SRC N/F from packet
private $dst = NULL; // DST N/F from packet
private $flags = NULL;
private $cost = 0;
private $flags = NULL; // Flags from packet
private $cost = 0; // Cost from packet
// @todo need to validate these string lengths when creating packet.
private $from = NULL; // FTS-0001.016 From Name: upto 36 chars null terminated
private $to = NULL; // FTS-0001.016 To Name: upto 36 chars null terminated
private $subject = NULL; // FTS-0001.016 Subject: upto 72 chars null terminated
@@ -31,8 +40,9 @@ class FTNMessage extends FTN
private $_other = [];
private $unknown = [];
private $fqfa = NULL; // Fully qualified fidonet source where packet originated
private $fqda = NULL; // Fully qualified fidonet destination address (Netmail)
// We auto create these values - they are used to create packets.
private $_fqfa = NULL; // Fully qualified fidonet source where packet originated
private $_fqda = NULL; // Fully qualified fidonet destination address (Netmail)
// Single value kludge items
private $_kludge = [
@@ -90,15 +100,30 @@ class FTNMessage extends FTN
{
switch ($k)
{
case 'fz': return $this->znfp($this->fqfa,'z');
case 'fn': return $this->znfp($this->fqfa,'n');
case 'ff': return $this->znfp($this->fqfa,'f');
case 'fp': return $this->znfp($this->fqfa,'p');
case 'fz': return ftn_address_split($this->_fqfa,'z');
case 'fn': return ftn_address_split($this->_fqfa,'n');
case 'ff': return ftn_address_split($this->_fqfa,'f');
case 'fp': return ftn_address_split($this->_fqfa,'p');
case 'tz': return $this->znfp($this->fqda,'z');
case 'tn': return $this->znfp($this->fqda,'n');
case 'tf': return $this->znfp($this->fqda,'f');
case 'tp': return $this->znfp($this->fqda,'p');
case 'fqfa': return $this->_fqfa;
// Echomails dont have a fully qualified from address
case 'tz': return ftn_address_split($this->_fqda,'z');
case 'tn': return ftn_address_split($this->_fqda,'n');
case 'tf': return ftn_address_split($this->_fqda,'f');
case 'tp': return ftn_address_split($this->_fqda,'p');
case 'tearline':
return '--- FTNHub';
case 'type':
if ($this->echoarea)
return 'echomail';
if ($this->intl)
return 'netmail';
return NULL;
default:
return isset($this->{$k}) ? $this->{$k} : NULL;
@@ -111,10 +136,17 @@ class FTNMessage extends FTN
{
case 'fqfa':
case 'fqda':
$this->{$k} = $v;
$this->{'_'.$k} = $v;
if ($this->fqfa AND $this->fqda)
$this->intl = sprintf('%s %s',$this->fqda,$this->fqfa);
if ($this->_fqfa AND $this->_fqda)
$this->intl = sprintf('%s %s',$this->_fqda,$this->_fqfa);
case 'origin':
if (! $this->_fqfa)
throw new \Exception('Must set from address before origin');
$this->origin = sprintf(' * Origin: %s (%s)',$v,$this->_fqfa);
break;
default:
$this->{$k} = $v;
@@ -128,6 +160,7 @@ class FTNMessage extends FTN
*/
public function __toString(): string
{
// if (f->net == 65535) { /* Point packet - Get Net from auxNet */
$return = '';
$return .= pack(join('',collect($this->struct)->pluck(1)->toArray()),
@@ -136,7 +169,7 @@ class FTNMessage extends FTN
$this->fn,
$this->tn,
$this->flags,
0 // @todo cost
$this->cost
);
// @todo use pack for this.
@@ -144,22 +177,45 @@ class FTNMessage extends FTN
$return .= $this->to."\00";
$return .= $this->from."\00";
$return .= $this->subject."\00";
$return .= $this->message."\00";
// Add some kludges
$return .= "\01MSGID ".$this->_fqfa." 1"."\r";
foreach ($this->_kludge as $k=>$v)
{
if ($x=$this->kludge->get($k))
$return .= chr(1).$v.$x."\r";
}
$return .= $this->message."\r";
$return .= $this->tearline."\r";
$return .= $this->origin."\r";
switch ($this->type)
{
case 'echomail':
break;
case 'netmail':
foreach ($this->via as $k=>$v)
$return .= "\01Via: ".$v."\r";
// @todo Set product name/version as var
$return .= sprintf('%sVia: %s @%s.UTC %s %i.%i',
chr(1),
'10:0/0',
now('UTC')->format('Ymd.His'),
'FTNHub',
1,1)."\r";
break;
}
$return .= "\00";
return $return;
}
public function description()
{
switch ($this->type())
{
case 'echomail': return sprintf('Echomail: '.$this->echoarea);
case 'netmail': return sprintf('Netmail: %s->%s',$this->fqfa,$this->fqda);
default:
return 'UNKNOWN';
}
}
/**
* Return an array of flag descriptions
*
@@ -215,25 +271,25 @@ class FTNMessage extends FTN
$result = unpack($this->unpackheader($this->struct),$header);
// For Echomail this is the packet src.
$this->psn = array_get($result,'onet');
$this->psf = array_get($result,'onode');
$this->psn = Arr::get($result,'onet');
$this->psf = Arr::get($result,'onode');
$this->_src = sprintf('%s/%s',
$this->src = sprintf('%s/%s',
$this->psn,
$this->psf
);
// For Echomail this is the packet dst.
$this->pdn = array_get($result,'dnet');
$this->pdf = array_get($result,'dnode');
$this->pdn = Arr::get($result,'dnet');
$this->pdf = Arr::get($result,'dnode');
$this->_dst = sprintf('%s/%s',
$this->dst = sprintf('%s/%s',
$this->pdn,
$this->pdf
);
$this->flags = array_get($result,'flags');
$this->cost = array_get($result,'cost');
$this->flags = Arr::get($result,'flags');
$this->cost = Arr::get($result,'cost');
}
public function parsemessage(string $message)
@@ -259,14 +315,33 @@ class FTNMessage extends FTN
{
$this->message .= substr($v,$x+1,$y-$x-1);
$this->parseorigin(substr($v,$y));
// If this is netmail, the FQFA will have been set by the INTL line, we can skip the rest of this
$matches = [];
// Capture the fully qualified 4D name from the Origin Line - it tells us the ZONE.
preg_match('/^.*\((.*)\)$/',$this->origin,$matches);
if (($this->type() == 'Netmail' AND array_get($matches,1) != $this->fqfa) OR ! array_get($matches,1))
throw new InvalidFidoPacketException(sprintf('Source address mismatch? [%s,%s]',$this->fqfa,array_get($matches,1)));
// Double check we have an address in the origin line
if (! Arr::get($matches,1))
throw new InvalidFidoPacketException(sprintf('No address in Origin?',$matches));
$this->fqfa = array_get($matches,1);
// Double check, our src and origin match
if (! preg_match('#^[0-9]+:'.$this->src.'#',$matches[1]))
throw new InvalidFidoPacketException(sprintf('Source address mismatch? [%s,%s]',$this->_fqfa,$matches[1]));
// If this is netmail, a double check our FQFA matches
if ($this->type == 'netmail') {
if ($this->_fqfa != $matches[1])
throw new InvalidFidoPacketException(sprintf('Source address mismatch? [%s,%s]',$this->_fqfa,$matches[1]));
// For other types, this is our only way of getting a FQFA
} else {
$this->_fqfa = $matches[1];
// Our FQDA is not available, we'll assume its the same zone as our FQFA
$this->_fqda = sprintf('%d:%s',ftn_address_split($this->_fqfa,'z'),$this->dst);
}
}
$v = substr($v,0,$x+1);
@@ -299,7 +374,7 @@ class FTNMessage extends FTN
elseif ($t = $this->kludge('INTL ',$v))
{
$this->intl = $t;
list($this->fqda,$this->fqfa) = explode(' ',$t);
list($this->_fqda,$this->_fqfa) = explode(' ',$t);
}
elseif ($t = $this->kludge('MSGID: ',$v))
@@ -344,10 +419,9 @@ class FTNMessage extends FTN
$result = collect(explode("\r",$message))->filter();
foreach ($result as $k => $v) {
foreach ($this->_kludge as $a => $b) {
if ($t = $this->kludge($b, $v)) {
$this->kludge->put($a, $t);
if ($t = $this->kludge($b,$v)) {
$this->kludge->put($a,$t);
break;
}
}
@@ -369,35 +443,4 @@ class FTNMessage extends FTN
}
}
}
public function type()
{
if ($this->echoarea)
return 'echomail';
if ($this->intl)
return 'netmail';
return 'UNKNOWN';
}
private function znfp(string $data,string $key)
{
switch ($key) {
case 'z':
return substr($data,0,strpos($data,':'));
case 'n':
$x = strpos($data,':')+1;
return substr($data,$x,strpos($data,'/')-$x);
case 'f':
$x = strpos($data,'/')+1;
return substr($data,$x,strpos($data,'.') ?: strlen($data)-$x);
case 'p':
$x = strpos($data,'.');
return $x ? substr($data,$x+1) : 0;
default:
abort(500,'Unknown key: '.$key);
}
}
}