40 lines
1.4 KiB
PHP
40 lines
1.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LayLink\Route;
|
|
|
|
use LayLink\Auth\PolicyChecker;
|
|
use LayLink\Node\NodeRegistry;
|
|
|
|
final class RouteResolver
|
|
{
|
|
public function __construct(
|
|
private readonly PolicyChecker $policyChecker,
|
|
private readonly NodeRegistry $nodeRegistry,
|
|
) {
|
|
}
|
|
|
|
public function resolve(string $userId, string $host, int $port, string $protocol, ?string $routeHint): RouteDecision
|
|
{
|
|
$policy = $this->policyChecker->find($userId, $host, $port, $protocol);
|
|
if ($policy === null) {
|
|
return new RouteDecision(false, 'reject', null, null, 'policy_denied');
|
|
}
|
|
|
|
$routeType = (string)($policy['route_type'] ?? 'reject');
|
|
$nodeId = $policy['node_id'] ?? null;
|
|
if (($routeType === 'agent' || $routeType === 'border') && $protocol !== 'udp') {
|
|
$nodeId = is_string($nodeId) && $nodeId !== '' ? $nodeId : $routeHint;
|
|
if (!is_string($nodeId) || $nodeId === '') {
|
|
return new RouteDecision(false, 'reject', null, (string)$policy['policy_id'], 'route_not_found');
|
|
}
|
|
if (!$this->nodeRegistry->isOnline($nodeId)) {
|
|
return new RouteDecision(false, 'reject', $nodeId, (string)$policy['policy_id'], 'node_offline');
|
|
}
|
|
}
|
|
|
|
return new RouteDecision(true, $routeType, $nodeId, (string)$policy['policy_id']);
|
|
}
|
|
}
|