big update all menus
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Nas;
|
||||
|
||||
use App\Models\NasMikrotik;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class RadiusHealthService
|
||||
{
|
||||
public function testConnection(NasMikrotik $radius): array
|
||||
{
|
||||
if (! $radius->host || ! $radius->radius_secret) {
|
||||
throw ValidationException::withMessages(['radius' => 'Host dan shared secret RADIUS wajib lengkap.']);
|
||||
}
|
||||
|
||||
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||||
if ($socket === false) {
|
||||
throw ValidationException::withMessages(['radius' => 'Socket UDP untuk RADIUS tidak dapat dibuat.']);
|
||||
}
|
||||
$timeout = max(1, min((int) ($radius->timeout ?: 5), 10));
|
||||
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $timeout, 'usec' => 0]);
|
||||
$identifier = random_int(0, 255);
|
||||
$requestAuthenticator = random_bytes(16);
|
||||
$request = pack('CCn', 12, $identifier, 20).$requestAuthenticator;
|
||||
$startedAt = hrtime(true);
|
||||
|
||||
try {
|
||||
$sent = @socket_sendto(
|
||||
$socket,
|
||||
$request,
|
||||
strlen($request),
|
||||
0,
|
||||
$radius->host,
|
||||
(int) ($radius->radius_auth_port ?: 1812),
|
||||
);
|
||||
if ($sent === false) {
|
||||
throw ValidationException::withMessages(['radius' => 'Status-Server RADIUS gagal dikirim.']);
|
||||
}
|
||||
$response = '';
|
||||
$from = '';
|
||||
$port = 0;
|
||||
$received = @socket_recvfrom($socket, $response, 4096, 0, $from, $port);
|
||||
if ($received === false || $received < 20) {
|
||||
throw ValidationException::withMessages([
|
||||
'radius' => 'RADIUS tidak merespons Status-Server. Pastikan Status-Server diizinkan oleh server.',
|
||||
]);
|
||||
}
|
||||
|
||||
['code' => $code, 'identifier' => $responseIdentifier, 'length' => $length] = unpack('Ccode/Cidentifier/nlength', substr($response, 0, 4));
|
||||
if ($responseIdentifier !== $identifier || $length > strlen($response)) {
|
||||
throw ValidationException::withMessages(['radius' => 'Respons RADIUS tidak valid.']);
|
||||
}
|
||||
$attributes = substr($response, 20, $length - 20);
|
||||
$expected = md5(substr($response, 0, 4).$requestAuthenticator.$attributes.$radius->radius_secret, true);
|
||||
if (! hash_equals($expected, substr($response, 4, 16))) {
|
||||
throw ValidationException::withMessages(['radius' => 'Authenticator respons RADIUS tidak valid.']);
|
||||
}
|
||||
|
||||
return [
|
||||
'connected' => true,
|
||||
'latency_ms' => (int) round((hrtime(true) - $startedAt) / 1_000_000),
|
||||
'host' => $radius->host,
|
||||
'auth_port' => (int) ($radius->radius_auth_port ?: 1812),
|
||||
'accounting_port' => (int) ($radius->radius_accounting_port ?: 1813),
|
||||
'response_code' => $code,
|
||||
'probe' => 'radius_status_server',
|
||||
];
|
||||
} finally {
|
||||
socket_close($socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user