Author: jfthomps
Date: Wed Oct  1 18:51:56 2014
New Revision: 1628807

URL: http://svn.apache.org/r1628807
Log:
VCL-174 - NAT - support for sites that have small IP address ranges

computer.php: modified validateResourceData: if natenabled or nathostid 
changed, check for active reservations on the computer; if found, report error 
that NAT settings cannot be changed during active reservations

requests.php: modified AJconnectRequest: substitute all port information from 
connectmethodports and natports for each connectmethod

utils.php:
-modified getImageConnectMethodTexts: added connectmethodport data to array of 
data returned for each connectmethod
-modified getRequestInfo: removed connectport from returned data; modified 
query to use rh.natIP as connectIP or, if that is NULL, use computer.IPaddress
-added getReservationNATports
-modified sendRDPfile: use connectmethods and natports to determine if a port 
should be appended to 'full address'

xmlrpcWrappers.php: modified XMLRPCgetRequestConnectData: return port data 
based on combination of connectmethods connectmethodports, and natports

Modified:
    vcl/trunk/web/.ht-inc/computer.php
    vcl/trunk/web/.ht-inc/requests.php
    vcl/trunk/web/.ht-inc/utils.php
    vcl/trunk/web/.ht-inc/xmlrpcWrappers.php

Modified: vcl/trunk/web/.ht-inc/computer.php
URL: 
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/computer.php?rev=1628807&r1=1628806&r2=1628807&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/computer.php (original)
+++ vcl/trunk/web/.ht-inc/computer.php Wed Oct  1 18:51:56 2014
@@ -1871,10 +1871,12 @@ class Computer extends Resource {
                        $return['error'] = 1;
                        $errormsg[] = "Invalid value submitted for Predictive 
Loading Module";
                }
+               $naterror = 0;
                # natenabled
                if($return['natenabled'] != 0 && $return['natenabled'] != 1) {
                        $return['error'] = 1;
                        $errormsg[] = "Invalid value for Connect Using NAT";
+                       $naterror = 1;
                }
                # nathostid
                $nathosts = getNAThosts();
@@ -1882,6 +1884,24 @@ class Computer extends Resource {
                   ($return['nathostid'] != 0 && ! 
array_key_exists($return['nathostid'], $nathosts))) {
                        $return['error'] = 1;
                        $errormsg[] = "Invalid value submitted for NAT Host";
+                       $naterror = 1;
+               }
+               # nat change - check for active reservations
+               if(! $naterror && ($olddata['natenabled'] != 
$return['natenabled'] ||
+                  $olddata['nathostid'] != $return['nathostid'])) {
+                       $query = "SELECT rq.id "
+                              . "FROM request rq, "
+                              .      "reservation rs "
+                              . "WHERE rs.requestid = rq.id AND "
+                              .       "rs.computerid = {$return['rscid']} AND "
+                              .       "rq.start <= NOW() AND "
+                              .       "rq.end > NOW() AND "
+                              .       "rq.stateid NOT IN (1,5,11,12)";
+                       $qh = doQuery($query);
+                       if(mysql_num_rows($qh)) {
+                               $return['error'] = 1;
+                               $errormsg[] = "This computer has an active 
reservation. NAT settings cannot be changed for computers having<br>active 
reservations.";
+                       }
                }
                # location
                if(! preg_match('/^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$/', 
$return['location'])) {

Modified: vcl/trunk/web/.ht-inc/requests.php
URL: 
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/requests.php?rev=1628807&r1=1628806&r2=1628807&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/requests.php (original)
+++ vcl/trunk/web/.ht-inc/requests.php Wed Oct  1 18:51:56 2014
@@ -4072,7 +4072,6 @@ function AJconnectRequest() {
                $h .= _("different environments in your cluster.<br><br>\n");
        }
        foreach($requestData["reservations"] as $key => $res) {
-               $serverIP = $res["reservedIP"];
                $osname = $res["OS"];
                if(array_key_exists($user['id'], 
$requestData['passwds'][$res['reservationid']]))
                        $passwd = 
$requestData['passwds'][$res['reservationid']][$user['id']];
@@ -4080,12 +4079,16 @@ function AJconnectRequest() {
                        $passwd = '';
                $connectData = getImageConnectMethodTexts($res['imageid'],
                                                          
$res['imagerevisionid']);
+               $natports = getNATports($res['reservationid']);
+               $usenat = 0;
+               if(count($natports))
+                       $usenat = 1;
                $first = 1;
                if($cluster) {
                        $h .= "<fieldset>\n";
                        $h .= 
"<legend><big><strong>{$res['prettyimage']}</strong></big></legend>\n";
                }
-               foreach($connectData as $method) {
+               foreach($connectData as $cmid => $method) {
                        if($first)
                                $first = 0;
                        else
@@ -4104,15 +4107,17 @@ function AJconnectRequest() {
                                $h .= "<h3>" . _("Connect to reservation 
using") . " {$method['description']}</h3>\n";
                        $froms = array('/#userid#/',
                                       '/#password#/',
-                                      '/#connectIP#/',
-                                      '/#connectport#/');
-                       if(empty($res['connectIP']))
-                               $res['connectIP'] = $serverIP; #TODO delete 
this when vcld is populating connectIP
+                                      '/#connectIP#/');
                        $tos = array($conuser,
                                     $passwd,
-                                    $res['connectIP'], 
-                                    $res['connectport']);
+                                    $res['connectIP']);
                        $msg = preg_replace($froms, $tos, 
$method['connecttext']); 
+                       foreach($method['ports'] as $port) {
+                               if($usenat && array_key_exists($port['key'], 
$natports[$cmid]))
+                                       $msg = preg_replace("/{$port['key']}/", 
$natports[$cmid][$port['key']]['publicport'], $msg); 
+                               else
+                                       $msg = preg_replace("/{$port['key']}/", 
$port['port'], $msg); 
+                       }
                        #$h .= preg_replace("/(.{1,120}([ ]|$))/", '\1<br>', 
$msg);
                        $h .= $msg;
                        if(preg_match('/remote desktop/i', 
$method['description']) ||

Modified: vcl/trunk/web/.ht-inc/utils.php
URL: 
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/utils.php?rev=1628807&r1=1628806&r2=1628807&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/utils.php (original)
+++ vcl/trunk/web/.ht-inc/utils.php Wed Oct  1 18:51:56 2014
@@ -1667,6 +1667,17 @@ function getImageConnectMethodTexts($ima
                                $textfield = "connecttext_$locale";
                }
        }
+       $cmports = array();
+       $query = "SELECT id, "
+              .        "connectmethodid, "
+              .        "port, "
+              .        "protocol "
+              . "FROM connectmethodport";
+       $qh = doQuery($query);
+       while($row = mysql_fetch_assoc($qh)) {
+               $row['key'] = "#Port-{$row['protocol']}-{$row['port']}#";
+               $cmports[$row['connectmethodid']][] = $row;
+       }
        if($revisionid == 0)
                $revisionid = getProductionRevisionid($imageid);
        $query = "SELECT c.id, "
@@ -1695,7 +1706,8 @@ function getImageConnectMethodTexts($ima
                }
                else
                        $methods[$row['id']] = array('description' => 
$row['description'],
-                                                    'connecttext' => 
$row['connecttext']);
+                                                    'connecttext' => 
$row['connecttext'],
+                                                    'ports' => 
$cmports[$row['id']]);
        }
        return $methods;
 }
@@ -5369,7 +5381,6 @@ function findManagementNode($compid, $st
 /// \b forcheckout - whether or not the image is intended for checkout\n
 /// \b password - password for this computer\n
 /// \b connectIP - IP to which user will connect\n
-/// \b connectport - port to which user will connect\n
 /// \b remoteIP - IP of remote user\n\n
 /// an array of arrays of passwords whose key is 'passwds', with the next key
 /// being the reservationid and the elements being the userid as a key and that
@@ -5426,14 +5437,15 @@ function getRequestInfo($id, $returnNULL
               .        "c.hostname, "
               .        "i.forcheckout, "
               .        "rs.pw AS password, "
-              .        "rs.connectIP, "
-              .        "rs.connectport, "
+              .        "COALESCE(nh.natIP, c.IPaddress) AS connectIP, "
               .        "rs.remoteIP "
               . "FROM reservation rs, "
               .      "image i, "
               .      "imagerevision ir, "
               .      "OS o, "
               .      "computer c "
+              . "LEFT JOIN natmap n ON (c.id = n.computerid) "
+              . "LEFT JOIN nathost nh ON (n.nathostid = nh.id) "
               . "WHERE rs.requestid = $id AND "
               .       "rs.imageid = i.id AND "
               .       "rs.imagerevisionid = ir.id AND "
@@ -8622,7 +8634,6 @@ function getUsedBlockComputerids($start,
        return $compids;
 }
 
-
 
////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn getNAThosts($id=0, $sort=0)
@@ -8660,6 +8671,42 @@ function getNAThosts($id=0, $sort=0) {
 
 
////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn getReservationNATports($resid)
+///
+/// \param $resid - id of a reservation
+///
+/// \return an array of arrays of NAT ports for $resid; the first level index
+/// is the connectmethod id; the second level index is the key used for
+/// substituting the port in the connectmethod text; each second level element
+/// has the following items\n
+/// \b publicport\n
+/// \b connectmethodportid\n
+/// \b privateport\n
+/// \b protocol\n
+/// \b connectmethodid
+///
+/// \brief builds an array of NAT port connection method data for a reservation
+///
+////////////////////////////////////////////////////////////////////////////////
+function getNATports($resid) {
+       $ports = array();
+       $query = "SELECT n.publicport, "
+              .        "n.connectmethodportid, " 
+              .        "c.port AS privateport, " 
+              .        "c.protocol, "
+              .        "c.connectmethodid "
+              . "FROM natport n, "
+              .      "connectmethodport c "
+              . "WHERE n.connectmethodportid = c.id AND "
+              .       "n.reservationid = $resid";
+       $qh = doQuery($query);
+       while($row = mysql_fetch_assoc($qh))
+               
$ports[$row['connectmethodid']]["#Port-{$row['protocol']}-{$row['privateport']}#"]
 = $row;
+       return $ports;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn getBlockTimeData($start, $end)
 ///
 /// \param $start - (optional) start time of blockTimes to get in unix 
timestamp
@@ -9613,7 +9660,7 @@ function sendRDPfile() {
        }
        foreach($request["reservations"] as $res) {
                if($res['reservationid'] == $resid) {
-                       $ipaddress = $res["reservedIP"];
+                       $ipaddress = $res["connectIP"];
                        break;
                }
        }
@@ -9621,6 +9668,22 @@ function sendRDPfile() {
                return;
        $passwd = $request['passwds'][$resid][$user['id']];
 
+       $connectData = getImageConnectMethodTexts($res['imageid'],
+                                                 $res['imagerevisionid']);
+       $natports = getNATports($resid);
+       $port = '';
+       foreach($connectData as $cmid => $method) {
+               if(preg_match('/remote desktop/i', $method['description']) ||
+                  preg_match('/RDP/i', $method['description'])) {
+                       # assume index 0 of ports for nat
+                       if(! empty($natports) && 
array_key_exists($method['ports'][0]['key'], $natports[$cmid]))
+                               $port = ':' . 
$natports[$cmid][$method['ports'][0]['key']]['publicport'];
+                       else
+                               $port = ':' . $method['ports'][0]['port'];
+                       break;
+               }
+       }
+
        $width = $user["width"];
        $height = $user["height"];
        if($width == 0) {
@@ -9653,7 +9716,7 @@ function sendRDPfile() {
        print "desktopheight:i:$height\r\n";
        print "session bpp:i:$bpp\r\n";
        print "winposstr:s:0,1,382,71,1182,671\r\n";
-       print "full address:s:$ipaddress\r\n";
+       print "full address:s:$ipaddress$port\r\n";
        print "compression:i:1\r\n";
        print "keyboardhook:i:2\r\n";
        print "audiomode:i:$audiomode\r\n";

Modified: vcl/trunk/web/.ht-inc/xmlrpcWrappers.php
URL: 
http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php?rev=1628807&r1=1628806&r2=1628807&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/xmlrpcWrappers.php (original)
+++ vcl/trunk/web/.ht-inc/xmlrpcWrappers.php Wed Oct  1 18:51:56 2014
@@ -776,12 +776,11 @@ function XMLRPCgetRequestConnectData($re
                       . "WHERE requestid = $requestid";
                $qh = doQuery($query, 101);
                addChangeLogEntry($requestData["logid"], $remoteIP);
-               $serverIP = $requestData["reservations"][0]["reservedIP"];
+               $serverIP = $requestData["reservations"][0]["connectIP"];
                $passwd = $requestData["reservations"][0]["password"];
-               $connectport = $requestData["reservations"][0]["connectport"];
                $connectMethods = getImageConnectMethodTexts(
-               $requestData["reservations"][0]["imageid"],
-               $requestData["reservations"][0]["imagerevisionid"]);
+                                    $requestData["reservations"][0]["imageid"],
+                                    
$requestData["reservations"][0]["imagerevisionid"]);
                if($requestData["forimaging"])
                        $thisuser = 'Administrator';
                else
@@ -789,13 +788,34 @@ function XMLRPCgetRequestConnectData($re
                                $thisuser = $matches[1];
                        else
                                $thisuser = $user['unityid'];
+               $natports = 
getNATports($requestData['reservations'][0]['reservationid']);
+               $portdata = array();
                foreach($connectMethods as $key => $cm) {
                        $connecttext = $cm["connecttext"];
                        $connecttext = preg_replace("/#userid#/", $thisuser, 
$connecttext); 
                        $connecttext = preg_replace("/#password#/", $passwd, 
$connecttext); 
                        $connecttext = preg_replace("/#connectIP#/", $serverIP, 
$connecttext); 
-                       $connecttext = preg_replace("/#connectport#/", 
$connectport, $connecttext); 
+                       foreach($cm['ports'] as $port) {
+                               if(! empty($natports) && 
array_key_exists($port['key'], $natports[$key])) {
+                                       $connecttext = 
preg_replace("/{$port['key']}/", $natports[$key][$port['key']]['publicport'], 
$connecttext); 
+                                       $connectMethods[$key]['connectports'][] 
= 
"{$port['protocol']}:{$port['port']}:{$natports[$key][$port['key']]['publicport']}";
+                               }
+                               else {
+                                       $connecttext = 
preg_replace("/{$port['key']}/", $port['port'], $connecttext); 
+                                       $connectMethods[$key]['connectports'][] 
= "{$port['protocol']}:{$port['port']}:{$port['port']}";
+                               }
+                       }
                        $connectMethods[$key]["connecttext"] = $connecttext;
+                       $portdata[$key] = $connectMethods[$key]['ports'];
+                       unset($connectMethods[$key]['ports']);
+               }
+               $tmp = array_keys($portdata);
+               $cmid = $tmp[0];
+               if(empty($natports))
+                       $connectport = $portdata[$cmid][0]['port'];
+               else {
+                       $key = $portdata[$cmid][0]['key'];
+                       $connectport = $natports[$cmid][$key]['publicport'];
                }
                return array('status' => 'ready',
                             'serverIP' => $serverIP,


Reply via email to