Compare commits
3 Commits
28b48e5bef
...
bee7e5d64a
Author | SHA1 | Date | |
---|---|---|---|
bee7e5d64a | |||
60214d3fbc | |||
9aecd61a2f |
@ -31,7 +31,7 @@ REDIS_PASSWORD=
|
|||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MAIL_DRIVER=smtp
|
MAIL_DRIVER=smtp
|
||||||
MAIL_HOST=mail.dege.lan
|
MAIL_HOST=smtp
|
||||||
MAIL_PORT=25
|
MAIL_PORT=25
|
||||||
MAIL_USERNAME=
|
MAIL_USERNAME=
|
||||||
MAIL_PASSWORD=
|
MAIL_PASSWORD=
|
||||||
@ -49,6 +49,7 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
|||||||
FIDO_DIR=fido
|
FIDO_DIR=fido
|
||||||
FIDO_PACKET_KEEP=
|
FIDO_PACKET_KEEP=
|
||||||
FIDO_STRICT=false
|
FIDO_STRICT=false
|
||||||
|
FIDO_HAPROXY=false
|
||||||
|
|
||||||
FILESYSTEM_DISK=s3
|
FILESYSTEM_DISK=s3
|
||||||
AWS_ACCESS_KEY_ID=
|
AWS_ACCESS_KEY_ID=
|
||||||
@ -61,3 +62,9 @@ AWS_USE_PATH_STYLE_ENDPOINT=true
|
|||||||
MATRIX_SERVER=
|
MATRIX_SERVER=
|
||||||
MATRIX_AS_TOKEN=
|
MATRIX_AS_TOKEN=
|
||||||
MATRIX_HS_TOKEN=
|
MATRIX_HS_TOKEN=
|
||||||
|
|
||||||
|
FIDO_DNS_NS=
|
||||||
|
FIDO_IP_AAAA=
|
||||||
|
FIDO_AAAA_ORDER=
|
||||||
|
FIDO_IP_A=
|
||||||
|
FIDO_A_ORDER=
|
||||||
|
@ -59,80 +59,131 @@ final class SocketClient {
|
|||||||
if ((! $originate) && config('fido.haproxy')) {
|
if ((! $originate) && config('fido.haproxy')) {
|
||||||
Log::debug(sprintf('%s:+ HAPROXY connection host [%s] on port [%d] (%s)',self::LOGKEY,$this->address_remote,$this->port_remote,$this->type));
|
Log::debug(sprintf('%s:+ HAPROXY connection host [%s] on port [%d] (%s)',self::LOGKEY,$this->address_remote,$this->port_remote,$this->type));
|
||||||
|
|
||||||
if ($this->read(5,12) !== "\x0d\x0a\x0d\x0a\x00\x0d\x0aQUIT\x0a")
|
if (($x=$this->read(5,6)) === 'PROXY ')
|
||||||
|
$vers = 1;
|
||||||
|
|
||||||
|
elseif (($x === "\x0d\x0a\x0d\x0a\x00\x0d") && ($this->read('5,6') === "\x0aQUIT\x0a"))
|
||||||
|
$vers = 2;
|
||||||
|
|
||||||
|
else
|
||||||
throw new HAproxyException('Failed to initialise HAPROXY connection');
|
throw new HAproxyException('Failed to initialise HAPROXY connection');
|
||||||
|
|
||||||
// Version/Command
|
switch ($vers) {
|
||||||
$vc = $this->read_ch(5);
|
|
||||||
|
|
||||||
if (($x=($vc>>4)&0x7) !== 2)
|
|
||||||
throw new HAproxyException(sprintf('Unknown HAPROXY version [%d]',$x));
|
|
||||||
|
|
||||||
switch ($x=($vc&0x7)) {
|
|
||||||
// HAPROXY internal
|
|
||||||
case 0:
|
|
||||||
throw new HAproxyException('HAPROXY internal health-check');
|
|
||||||
|
|
||||||
// PROXY connection
|
|
||||||
case 1:
|
case 1:
|
||||||
|
// Protocol/Address Family
|
||||||
|
switch ($x=$this->read(5,5)) {
|
||||||
|
case 'TCP4 ':
|
||||||
|
$p = 4;
|
||||||
|
break;
|
||||||
|
case 'TCP6 ':
|
||||||
|
$p = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY protocol [%d] is not handled',$x));
|
||||||
|
}
|
||||||
|
|
||||||
|
$read = $this->read(5,104-11);
|
||||||
|
|
||||||
|
// IPv4
|
||||||
|
if (($p === 4) || ($p === 6)) {
|
||||||
|
$parse = collect(sscanf($read,'%s %s %s %s'));
|
||||||
|
|
||||||
|
$src = Arr::get($parse,0);
|
||||||
|
$dst = Arr::get($parse,1);
|
||||||
|
$src_port = (int)Arr::get($parse,2);
|
||||||
|
$dst_port = (int)Arr::get($parse,3);
|
||||||
|
$len = $parse->map(fn($item)=>strlen($item))->sum()+3;
|
||||||
|
|
||||||
|
// The last 2 chars should be "\r\n"
|
||||||
|
if (($x=substr($read,$len)) !== "\r\n")
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY parsing failed for version [%d] [%s] (%s)',$p,$read,hex_dump($x)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY version [%d] is not handled [%s]',$p,$read));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->port_remote = $src_port;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// Version/Command
|
||||||
|
$vc = $this->read_ch(5);
|
||||||
|
|
||||||
|
if (($x=($vc>>4)&0x7) !== 2)
|
||||||
|
throw new HAproxyException(sprintf('Unknown HAPROXY version [%d]',$x));
|
||||||
|
|
||||||
|
switch ($x=($vc&0x7)) {
|
||||||
|
// HAPROXY internal
|
||||||
|
case 0:
|
||||||
|
throw new HAproxyException('HAPROXY internal health-check');
|
||||||
|
|
||||||
|
// PROXY connection
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY command [%d] is not handled',$x));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protocol/Address Family
|
||||||
|
$pa = $this->read_ch(5);
|
||||||
|
|
||||||
|
switch ($x=($pa>>4)&0x7) {
|
||||||
|
case 1: // AF_INET
|
||||||
|
$p = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // AF_INET6
|
||||||
|
$p = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($x=($pa&0x7)) {
|
||||||
|
case 1: // STREAM
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY address family [%d] is not handled',$x));
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = Arr::get(unpack('n',$this->read(5,2)),1);
|
||||||
|
|
||||||
|
// IPv4
|
||||||
|
if (($p === 4) && ($len === 12)) {
|
||||||
|
$src = inet_ntop($this->read(5,4));
|
||||||
|
$dst = inet_ntop($this->read(5,4));
|
||||||
|
|
||||||
|
} elseif (($p === 6) && ($len === 36)) {
|
||||||
|
$src = inet_ntop($this->read(5,16));
|
||||||
|
$dst = inet_ntop($this->read(5,16));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new HAproxyException(sprintf('HAPROXY address len [%d:%d] is not handled',$p,$len));
|
||||||
|
}
|
||||||
|
|
||||||
|
$src_port = unpack('n',$this->read(5,2));
|
||||||
|
$dst_port = Arr::get(unpack('n',$this->read(5,2)),1);
|
||||||
|
|
||||||
|
$this->port_remote = Arr::get($src_port,1);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new HAproxyException(sprintf('HAPROXY command [%d] is not handled',$x));
|
throw new HAproxyException('Failed to initialise HAPROXY connection');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol/Address Family
|
|
||||||
$pa = $this->read_ch(5);
|
|
||||||
$p = NULL;
|
|
||||||
|
|
||||||
switch ($x=($pa>>4)&0x7) {
|
|
||||||
case 1: // AF_INET
|
|
||||||
$p = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // AF_INET6
|
|
||||||
$p = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new HAproxyException(sprintf('HAPROXY protocol [%d] is not handled',$x));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($x=($pa&0x7)) {
|
|
||||||
case 1: // STREAM
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new HAproxyException(sprintf('HAPROXY address family [%d] is not handled',$x));
|
|
||||||
}
|
|
||||||
|
|
||||||
$len = Arr::get(unpack('n',$this->read(5,2)),1);
|
|
||||||
|
|
||||||
// IPv4
|
|
||||||
if (($p === 4) && ($len === 12)) {
|
|
||||||
$src = inet_ntop($this->read(5,4));
|
|
||||||
$dst = inet_ntop($this->read(5,4));
|
|
||||||
|
|
||||||
} elseif (($p === 6) && ($len === 36)) {
|
|
||||||
$src = inet_ntop($this->read(5,16));
|
|
||||||
$dst = inet_ntop($this->read(5,16));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new HAproxyException(sprintf('HAPROXY address len [%d:%d] is not handled',$p,$len));
|
|
||||||
}
|
|
||||||
|
|
||||||
$src_port = unpack('n',$this->read(5,2));
|
|
||||||
$dst_port = unpack('n',$this->read(5,2));
|
|
||||||
|
|
||||||
$this->address_remote = $src;
|
$this->address_remote = $src;
|
||||||
$this->port_remote = Arr::get($src_port,1);
|
|
||||||
|
|
||||||
Log::debug(sprintf('%s:- HAPROXY src [%s:%d] dst [%s:%d]',
|
Log::debug(sprintf('%s:- HAPROXY src [%s:%d] dst [%s:%d]',
|
||||||
self::LOGKEY,
|
self::LOGKEY,
|
||||||
$this->address_remote,
|
$this->address_remote,
|
||||||
$this->port_remote,
|
$this->port_remote,
|
||||||
$dst,
|
$dst,
|
||||||
Arr::get($dst_port,1),
|
$dst_port,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +241,8 @@ final class SocketClient {
|
|||||||
{
|
{
|
||||||
Log::info(sprintf('%s:+ Creating connection to [%s:%d]',self::LOGKEY,$address,$port));
|
Log::info(sprintf('%s:+ Creating connection to [%s:%d]',self::LOGKEY,$address,$port));
|
||||||
|
|
||||||
$sort = collect(['AAAA','A']);
|
$type = collect(config('fido.ip'))
|
||||||
|
->filter(fn($item)=>$item['enabled']);
|
||||||
|
|
||||||
if (filter_var($address,FILTER_VALIDATE_IP))
|
if (filter_var($address,FILTER_VALIDATE_IP))
|
||||||
$resolved = collect([[
|
$resolved = collect([[
|
||||||
@ -199,9 +251,9 @@ final class SocketClient {
|
|||||||
]]);
|
]]);
|
||||||
else
|
else
|
||||||
// We only look at AAAA/A records
|
// We only look at AAAA/A records
|
||||||
$resolved = collect(dns_get_record($address,DNS_AAAA|DNS_A))
|
$resolved = collect(dns_get_record($address,$type->map(fn($item)=>$item['type'])->sum()))
|
||||||
->filter(function($item) use ($sort) { return $sort->search(Arr::get($item,'type')) !== FALSE; })
|
->filter(fn($item)=>$type->has(Arr::get($item,'type')))
|
||||||
->sort(function($item) use ($sort) { return $sort->search(Arr::get($item,'type')); });
|
->sort(fn($a,$b)=>$type->get(Arr::get($a,'type'))['order'] < $type->get(Arr::get($b,'type'))['order']);
|
||||||
|
|
||||||
if (! $resolved->count())
|
if (! $resolved->count())
|
||||||
throw new SocketException(SocketException::CANT_CONNECT,sprintf('%s doesnt resolved to an IPv4/IPv6 address',$address));
|
throw new SocketException(SocketException::CANT_CONNECT,sprintf('%s doesnt resolved to an IPv4/IPv6 address',$address));
|
||||||
|
@ -43,4 +43,18 @@ return [
|
|||||||
'down' => 35,
|
'down' => 35,
|
||||||
'delist' => 45,
|
'delist' => 45,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// IP Address Resolution preferences
|
||||||
|
'ip' => [
|
||||||
|
'AAAA' => [
|
||||||
|
'enabled' => env('FIDO_IP_AAAA',false),
|
||||||
|
'order' => env('FIDO_AAAA_ORDER',2),
|
||||||
|
'type' => DNS_AAAA,
|
||||||
|
],
|
||||||
|
'A' => [
|
||||||
|
'enabled' => env('FIDO_IP_A',TRUE),
|
||||||
|
'order' => env('FIDO_A_ORDER',1),
|
||||||
|
'type' => DNS_A,
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
Loading…
Reference in New Issue
Block a user