Do DNS resolve for node names via zone proxy. (issue #NX-1268)
authorzev <zev@netxms.org>
Wed, 25 Oct 2017 15:49:15 +0000 (18:49 +0300)
committerzev <zev@netxms.org>
Wed, 25 Oct 2017 15:52:50 +0000 (18:52 +0300)
ChangeLog
include/nms_cscp.h
src/agent/core/session.cpp
src/server/core/node.cpp
src/server/core/np.cpp
src/server/include/nms_objects.h
src/server/include/nxsrvapi.h
src/server/libnxsrv/agent.cpp

index d8c5275..02f0c80 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,7 +11,7 @@
 *
 
 - Per stage confirmation in database manager during database check
-- Fixed issues: NX-703, NX-1341, NX-1342, NX-1343, NX-1344
+- Fixed issues: NX-703, NX-1268, NX-1341, NX-1342, NX-1343, NX-1344
 
 
 *
index 4a97287..d362d8d 100644 (file)
@@ -591,6 +591,7 @@ typedef struct
 #define CMD_UNREGISTER_LORAWAN_SENSOR     0x0164
 #define CMD_EXPAND_MACROS                 0x0165
 #define CMD_EXECUTE_ACTION_WITH_EXPANSION 0x0166
+#define CMD_HOST_BY_IP                    0x0167
 
 #define CMD_RS_LIST_REPORTS            0x1100
 #define CMD_RS_GET_REPORT              0x1101
index aaef2dc..5762b11 100644 (file)
@@ -656,6 +656,14 @@ void CommSession::processingThread()
                                           response.setField(VID_RCC, ERR_ACCESS_DENIED);
                                        }
                                        break;
+            case CMD_HOST_BY_IP:
+            {
+               InetAddress addr = request->getFieldAsInetAddress(VID_IP_ADDRESS);
+               TCHAR dnsName[MAX_DNS_NAME];
+               response.setField(VID_NAME, addr.getHostByAddr(dnsName, MAX_DNS_NAME));
+               response.setField(VID_RCC, ERR_SUCCESS);
+               break;
+            }
             case CMD_SET_SERVER_CAPABILITIES:
                // Servers before 2.0 use VID_ENABLED
                m_ipv6Aware = request->isFieldExist(VID_IPV6_SUPPORT) ? request->getFieldAsBoolean(VID_IPV6_SUPPORT) : request->getFieldAsBoolean(VID_ENABLED);
index a07d3fc..02fa2ed 100644 (file)
@@ -5450,6 +5450,29 @@ AgentConnectionEx *Node::acquireProxyConnection(ProxyType type, bool validate)
 }
 
 /**
+ * Get connection to zone proxy node of this node
+ */
+AgentConnectionEx *Node::getConnectionToZoneNodeProxy(bool validate)
+{
+   Zone *zone = FindZoneByUIN(m_zoneUIN);
+   if (zone == NULL)
+   {
+     DbgPrintf(1, _T("Internal error: zone is NULL in Node::getZoneProxyConnection (zone ID = %d)"), (int)m_zoneUIN);
+     return NULL;
+   }
+
+   UINT32 zoneProxyNodeId = zone->getProxyNodeId();
+   Node *zoneNode = (Node *)FindObjectById(zoneProxyNodeId, OBJECT_NODE);
+   if(zoneNode == NULL)
+   {
+      DbgPrintf(1, _T("Internal error: zone proxy node is NULL in Node::getZoneProxyConnection (zone ID = %d, node ID = %d)"), (int)m_zoneUIN, (int)zoneProxyNodeId);
+      return NULL;
+   }
+
+   return zoneNode->acquireProxyConnection(ZONE_PROXY, validate);
+}
+
+/**
  * Set node's primary IP address.
  * Assumed that all necessary locks already in place
  */
@@ -6080,9 +6103,23 @@ BOOL Node::resolveName(BOOL useOnlyDNS)
 
    DbgPrintf(4, _T("Resolving name for node %d [%s]..."), m_id, m_name);
 
+   TCHAR *name;
+   TCHAR dnsName[MAX_OBJECT_NAME];
+   if(m_zoneUIN != 0)
+   {
+      AgentConnectionEx *conn = getConnectionToZoneNodeProxy();
+      if(conn->getHostByAddr(m_ipAddress, dnsName, MAX_DNS_NAME) != NULL)
+      {
+         name = dnsName;
+      }
+   }
+   else if (m_ipAddress.getHostByAddr(dnsName, MAX_OBJECT_NAME) != NULL)
+   {
+      name = dnsName;
+   }
+
    // Try to resolve primary IP
-   TCHAR name[MAX_OBJECT_NAME];
-   if (m_ipAddress.getHostByAddr(name, MAX_OBJECT_NAME) != NULL)
+   if (name != NULL)
    {
       nx_strncpy(m_name, name, MAX_OBJECT_NAME);
       if (!(g_flags & AF_USE_FQDN_FOR_NODE_NAMES))
index 119da34..9450400 100644 (file)
@@ -178,16 +178,27 @@ Node NXCORE_EXPORTABLE *PollNewNode(const InetAddress& ipAddr, UINT32 creationFl
        // Use DNS name as primary name if required
        if (discoveredNode && ConfigReadInt(_T("UseDNSNameForDiscoveredNodes"), 0))
        {
-               TCHAR dnsName[MAX_DNS_NAME];
-      if (ipAddr.getHostByAddr(dnsName, MAX_DNS_NAME) != NULL)
+      TCHAR dnsName[MAX_DNS_NAME];
+      TCHAR *tmp;
+          if(IsZoningEnabled() && zoneUIN != 0)
+          {
+             AgentConnectionEx *conn = pNode->getConnectionToZoneNodeProxy();
+             tmp = conn->getHostByAddr(ipAddr, dnsName, MAX_DNS_NAME);
+          }
+          else
                {
-         if (InetAddress::resolveHostName(dnsName).equals(ipAddr))
-                       {
-                               // We have valid DNS name which resolves back to node's IP address, use it as primary name
-                               pNode->setPrimaryName(dnsName);
-                               DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName, szIpAddr);
-                       }
+             tmp = ipAddr.getHostByAddr(dnsName, MAX_DNS_NAME);
                }
+
+      if(tmp != NULL)
+      {
+         if(ResolveHostName(zoneUIN, dnsName).equals(ipAddr))
+         {
+            // We have valid DNS name which resolves back to node's IP address, use it as primary name
+            pNode->setPrimaryName(dnsName);
+            DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName, szIpAddr);
+         }
+      }
        }
 
        // Bind node to cluster before first configuration poll
index 46eda3f..ac7cbcb 100644 (file)
@@ -1630,7 +1630,8 @@ enum ProxyType
 {
    SNMP_PROXY = 0,
    SENSOR_PROXY = 1,
-   MAX_PROXY_TYPE = 2
+   ZONE_PROXY = 2,
+   MAX_PROXY_TYPE = 3
 };
 
 /**
@@ -1989,6 +1990,7 @@ public:
 
    AgentConnectionEx *createAgentConnection(bool sendServerId = false);
    AgentConnectionEx *acquireProxyConnection(ProxyType type, bool validate = false);
+   AgentConnectionEx *getConnectionToZoneNodeProxy(bool validate = false);
        SNMP_Transport *createSnmpTransport(WORD port = 0, const TCHAR *context = NULL);
        SNMP_SecurityContext *getSnmpSecurityContext() const;
    UINT32 getEffectiveSnmpProxy() const;
index 1f71f58..c1923d6 100644 (file)
@@ -588,6 +588,7 @@ public:
        UINT32 getPolicyInventory(AgentPolicyInfo **info);
        UINT32 uninstallPolicy(const uuid& guid);
    UINT32 takeScreenshot(const TCHAR *sessionName, BYTE **data, size_t *size);
+   TCHAR *getHostByAddr(const InetAddress& ipAddr, TCHAR *buf, size_t bufLen);
 
        UINT32 generateRequestId() { return (UINT32)InterlockedIncrement(&m_requestId); }
        NXCPMessage *customRequest(NXCPMessage *pRequest, const TCHAR *recvFile = NULL, bool append = false,
index 91d2c6e..45bc7ca 100644 (file)
@@ -2049,6 +2049,43 @@ UINT32 AgentConnection::takeScreenshot(const TCHAR *sessionName, BYTE **data, si
 }
 
 /**
+ * Resolve hostname by IP address in local network
+ */
+TCHAR *AgentConnection::getHostByAddr(const InetAddress& ipAddr, TCHAR *buf, size_t bufLen)
+{
+   NXCPMessage msg(m_nProtocolVersion);
+   UINT32 dwRqId;
+
+   dwRqId = generateRequestId();
+   msg.setCode(CMD_HOST_BY_IP);
+   msg.setId(dwRqId);
+   msg.setField(VID_IP_ADDRESS, ipAddr);
+   TCHAR *result = NULL;
+   if (sendMessage(&msg))
+   {
+      NXCPMessage *response = waitForMessage(CMD_REQUEST_COMPLETED, dwRqId, m_dwCommandTimeout);
+      if (response != NULL)
+      {
+         UINT32 rcc = response->getFieldAsUInt32(VID_RCC);
+         if (rcc == ERR_SUCCESS)
+         {
+            result = response->getFieldAsString(VID_NAME, buf, bufLen);
+         }
+         delete response;
+         return result;
+      }
+      else
+      {
+         return result;
+      }
+   }
+   else
+   {
+      return result;
+   }
+}
+
+/**
  * Send custom request to agent
  */
 NXCPMessage *AgentConnection::customRequest(NXCPMessage *pRequest, const TCHAR *recvFile, bool append,