laylink/src/Route/RouteResolver.php
2026-05-28 20:19:28 +08:00

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']);
}
}