From 9a8569775996b4b2441b69e06a09b9ab8284519e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 7 Mar 2019 15:23:42 +0100 Subject: [dnbd3] Support specifying port, IPv6 addresses --- modules-available/dnbd3/inc/dnbd3rpc.inc.php | 17 +++++++++--- modules-available/dnbd3/inc/dnbd3util.inc.php | 22 +++++++++++++--- modules-available/dnbd3/lang/de/messages.json | 2 +- modules-available/dnbd3/lang/en/messages.json | 2 +- modules-available/dnbd3/page.inc.php | 38 +++++++++------------------ 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php index cdcda508..6ed43254 100644 --- a/modules-available/dnbd3/inc/dnbd3rpc.inc.php +++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php @@ -19,13 +19,24 @@ class Dnbd3Rpc { * @param bool $altservers list of alt servers with status * @return int|array the queried data as an array, or false on error */ - public static function query($server, $port, $stats, $clients, $images, $diskSpace = false, $config = false, $altservers = false) + public static function query($server, $stats, $clients, $images, $diskSpace = false, $config = false, $altservers = false) { // Special case - local server if ($server === '') { - $server = '127.0.0.1'; + $server = '127.0.0.1:5003'; + } elseif (($out = Dnbd3Util::matchAddress($server))) { + if (isset($out['v4'])) { + $server = $out['v4']; + } else { + $server = '[' . $out['v6'] . ']'; + } + if (isset($out['port'])) { + $server .= $out['port']; + } else { + $server .= ':5003'; + } } - $url = 'http://' . $server . ':' . $port . '/query?'; + $url = 'http://' . $server . '/query?'; if ($stats) { $url .= 'q=stats&'; } diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php index 33581b77..35fad8b3 100644 --- a/modules-available/dnbd3/inc/dnbd3util.inc.php +++ b/modules-available/dnbd3/inc/dnbd3util.inc.php @@ -52,12 +52,11 @@ class Dnbd3Util { // Now query them all $NOW = time(); foreach ($servers as $server) { - $port = 5003; - $data = Dnbd3Rpc::query($server['addr'], $port, true, false, false, true); + $data = Dnbd3Rpc::query($server['addr'], true, false, false, true); if ($data === Dnbd3Rpc::QUERY_UNREACHABLE) { - $error = 'No (HTTP) reply on port ' . $port; + $error = 'No (HTTP) reply from ' . $server['addr']; } elseif ($data === Dnbd3Rpc::QUERY_NOT_200) { - $error = 'No HTTP 200 OK on port ' . $port; + $error = 'No HTTP 200 OK from ' . $server['addr']; } elseif ($data === Dnbd3Rpc::QUERY_NOT_JSON) { $error = 'Reply to status query is not JSON'; } elseif (!is_array($data) || !isset($data['runId'])) { @@ -247,4 +246,19 @@ class Dnbd3Util { ); } + public static function matchAddress($server) + { + if (!preg_match('/^(?:\[(?[a-f0-9:]+)\]|(?[a-f0-9:]+)|(?[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+))(?:\d+)?$/i', + $server, $out)) { + return false; + } + foreach (['v6a', 'v6b'] as $k) { + if (isset($out[$k])) { + $out['v6'] = $out[$k]; + unset($out[$k]); + } + } + return $out; + } + } diff --git a/modules-available/dnbd3/lang/de/messages.json b/modules-available/dnbd3/lang/de/messages.json index 05b8f968..c64b35b7 100644 --- a/modules-available/dnbd3/lang/de/messages.json +++ b/modules-available/dnbd3/lang/de/messages.json @@ -1,6 +1,6 @@ { "dnbd3-proxy-unreachable": "DNBD3-Proxy {{0}} ist offline seit {{2}}. ({{1}})", - "invalid-ipv4": "{{0}} ist keine g\u00fcltige IPv4-Adresse", + "invalid-ip": "{{0}} ist keine g\u00fcltige Angabe von IP oder IP:Port", "main-dnbd3-unreachable": "Zentraler DNBD3-Server des Satelliten ist offline seit {{1}}. ({{0}})", "not-automatic-server": "{{0}} wird nicht \u00fcber den Satelliten verwaltet", "server-added": "Server {{0}} hinzugef\u00fcgt", diff --git a/modules-available/dnbd3/lang/en/messages.json b/modules-available/dnbd3/lang/en/messages.json index 731b4ad9..cf70aac3 100644 --- a/modules-available/dnbd3/lang/en/messages.json +++ b/modules-available/dnbd3/lang/en/messages.json @@ -1,6 +1,6 @@ { "dnbd3-proxy-unreachable": "DNBD3-Proxy {{0}} is offline since {{2}}. ({{1}}) ", - "invalid-ipv4": "{{0}} is no valid IPv4-Address", + "invalid-ip": "{{0}} is not valid IP or IP:Port", "main-dnbd3-unreachable": "Main DNBD3-Server of the satellite server is offline since {{1}}. ({{0}})", "not-automatic-server": "{{0}} is not managed by this satellite server", "server-added": "Server {{0}} added", diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index d2e8162b..4a32b0a3 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -47,22 +47,18 @@ class Page_Dnbd3 extends Page if (empty($sip)) { $overrideIp = null; } elseif ($server['fixedip'] !== $overrideIp) { - $ip = ip2long(trim($sip)); - if ($ip !== false) { - $ip = long2ip($ip); - } - if ($ip === false) { - Message::addError('invalid-ipv4', $sip); + if (Dnbd3Util::matchAddress($sip) === false) { + Message::addError('invalid-ip', $sip); return; } $res = Database::queryFirst('SELECT serverid FROM dnbd3_server s LEFT JOIN machine m USING (machineuuid) - WHERE s.fixedip = :ip OR m.clientip = :ip', compact('ip')); + WHERE s.fixedip = :ip OR m.clientip = :ip', ['ip' => $sip]); if ($res !== false) { - Message::addError('server-already-exists', $ip); + Message::addError('server-already-exists', $sip); return; } - $overrideIp = $ip; + $overrideIp = $sip; } if ($overrideIp !== false) { Database::exec('UPDATE dnbd3_server SET fixedip = :fixedip WHERE machineuuid = :uuid', array( @@ -110,12 +106,8 @@ class Page_Dnbd3 extends Page Message::addError('main.parameter-missing', 'ip'); return; } - $ip = ip2long(trim($ip)); - if ($ip !== false) { - $ip = long2ip($ip); - } - if ($ip === false) { - Message::addError('invalid-ipv4', $ip); + if (Dnbd3Util::matchAddress($ip) === false) { + Message::addError('invalid-ip', $ip); return; } $res = Database::queryFirst('SELECT serverid FROM dnbd3_server s @@ -264,7 +256,7 @@ class Page_Dnbd3 extends Page User::assertPermission('view.details'); $server = $this->getServerById(); Render::addTemplate('page-proxy-header', $server); - $stats = Dnbd3Rpc::query($server['ip'], 5003, true, true, true, true, true, true); + $stats = Dnbd3Rpc::query($server['ip'], true, true, true, true, true, true); if (!is_array($stats) || !isset($stats['runId'])) { Message::addError('server-unreachable'); return; @@ -473,14 +465,10 @@ class Page_Dnbd3 extends Page User::assertPermission('configure.external'); Header('Content-Type: application/json; charset=utf-8'); $ip = Request::post('ip', false, 'string'); - if ($ip === false) - die('{"error": "Missing parameter", "fatal": true}'); - $ip = ip2long(trim($ip)); - if ($ip !== false) { - $ip = long2ip($ip); - } - if ($ip === false) - die('{"error": "Supports IPv4 only", "fatal": true}'); + if (Dnbd3Util::matchAddress($ip) === false) { + die('{"error": "Supports IP addresses (with optional port) only, no hostnames", "fatal": true}'); + } + // Dup? $res = Database::queryFirst('SELECT serverid FROM dnbd3_server s LEFT JOIN machine m USING (machineuuid) @@ -488,7 +476,7 @@ class Page_Dnbd3 extends Page if ($res !== false) die('{"error": "Server with this IP already exists", "fatal": true}'); // Query - $reply = Dnbd3Rpc::query($ip, 5003,true, false, false, true); + $reply = Dnbd3Rpc::query($ip,true, false, false, true); if ($reply === Dnbd3Rpc::QUERY_UNREACHABLE) die('{"error": "Could not reach server"}'); if ($reply === Dnbd3Rpc::QUERY_NOT_200) -- cgit v1.2.3-55-g7522