application agent changed to use NamedPipeListener class
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 25 Oct 2017 12:08:36 +0000 (15:08 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 25 Oct 2017 12:08:36 +0000 (15:08 +0300)
src/appagent/.cproject [new file with mode: 0644]
src/appagent/.project [new file with mode: 0644]
src/appagent/appagent.cpp

diff --git a/src/appagent/.cproject b/src/appagent/.cproject
new file mode 100644 (file)
index 0000000..7d32422
--- /dev/null
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.2024948251">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.2024948251" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.2024948251" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="cdt.managedbuild.toolchain.gnu.base.2024948251.1948805007" name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.921164988" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.1389776938" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder id="cdt.managedbuild.target.gnu.builder.base.47124520" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.502735946" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1428489396" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.include.paths.540877274" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.717985134" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_THREAD_SAFE"/>
+                                                                       <listOptionValue builtIn="false" value="TRE_WCHAR=1"/>
+                                                                       <listOptionValue builtIn="false" value="UNICODE"/>
+                                                                       <listOptionValue builtIn="false" value="_GNU_SOURCE"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1909647748" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1082541740" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option id="gnu.c.compiler.option.include.paths.1981407059" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.c.compiler.option.preprocessor.def.symbols.1583484295" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_THREAD_SAFE"/>
+                                                                       <listOptionValue builtIn="false" value="TRE_WCHAR=1"/>
+                                                                       <listOptionValue builtIn="false" value="UNICODE"/>
+                                                                       <listOptionValue builtIn="false" value="_GNU_SOURCE"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.571833063" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.494130129" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.727817363" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.662203369" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.1928421973" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <option id="gnu.both.asm.option.include.paths.345118894" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.738343008" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="appagent.null.1930133643" name="appagent"/>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.2024948251;cdt.managedbuild.toolchain.gnu.base.2024948251.1948805007;cdt.managedbuild.tool.gnu.c.compiler.base.1082541740;cdt.managedbuild.tool.gnu.c.compiler.input.571833063">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.2024948251;cdt.managedbuild.toolchain.gnu.base.2024948251.1948805007;cdt.managedbuild.tool.gnu.cpp.compiler.base.1428489396;cdt.managedbuild.tool.gnu.cpp.compiler.input.1909647748">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+</cproject>
diff --git a/src/appagent/.project b/src/appagent/.project
new file mode 100644 (file)
index 0000000..758308e
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>appagent</name>
+       <comment></comment>
+       <projects>
+               <project>libnetxms</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+       <filteredResources>
+               <filter>
+                       <id>1508924421556</id>
+                       <name></name>
+                       <type>6</type>
+                       <matcher>
+                               <id>org.eclipse.ui.ide.multiFilter</id>
+                               <arguments>1.0-name-matches-false-false-*.o</arguments>
+                       </matcher>
+               </filter>
+               <filter>
+                       <id>1508924421558</id>
+                       <name></name>
+                       <type>6</type>
+                       <matcher>
+                               <id>org.eclipse.ui.ide.multiFilter</id>
+                               <arguments>1.0-name-matches-false-false-*.lo</arguments>
+                       </matcher>
+               </filter>
+               <filter>
+                       <id>1508924421559</id>
+                       <name></name>
+                       <type>6</type>
+                       <matcher>
+                               <id>org.eclipse.ui.ide.multiFilter</id>
+                               <arguments>1.0-name-matches-false-false-*.la</arguments>
+                       </matcher>
+               </filter>
+       </filteredResources>
+</projectDescription>
index de12fe8..5a8115f 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2013 Victor Kirhenshtein
+** Copyright (C) 2003-2017 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,7 @@
 **/
 
 #include "appagent-internal.h"
+#include <nxproc.h>
 
 #if defined(_AIX) || defined(__sun)
 #include <signal.h>
  * Application agent config
  */
 static APPAGENT_INIT s_config;
-static bool s_stop = false;
 static bool s_initialized = false;
-static HPIPE s_pipe = INVALID_PIPE_HANDLE;
-static THREAD s_connectorThread = INVALID_THREAD_HANDLE;
 
 /**
  * Write log
@@ -138,14 +136,14 @@ static APPAGENT_MSG *ListMetrics()
 /**
  * Process incoming request
  */
-static void ProcessRequest(HPIPE hPipe)
+static void ProcessRequest(NamedPipe *pipe, void *arg)
 {
        AppAgentMessageBuffer *mb = new AppAgentMessageBuffer;
 
        AppAgentWriteLog(7, _T("ProcessRequest: connection established"));
        while(true)
        {
-               APPAGENT_MSG *msg = ReadMessageFromPipe(hPipe, mb);
+               APPAGENT_MSG *msg = ReadMessageFromPipe(pipe->handle(), mb);
                if (msg == NULL)
                        break;
                AppAgentWriteLog(7, _T("ProcessRequest: received message %04X"), (unsigned int)msg->command);
@@ -163,200 +161,13 @@ static void ProcessRequest(HPIPE hPipe)
                                break;
                }
                free(msg);
-               SendMessageToPipe(hPipe, response);
+               SendMessageToPipe(pipe->handle(), response);
                free(response);
        }
        AppAgentWriteLog(7, _T("ProcessRequest: connection closed"));
        delete mb;
 }
 
-/**
- * Connector thread for application agent
- */
-#ifdef _WIN32
-
-static THREAD_RESULT THREAD_CALL AppAgentConnector(void *arg)
-{
-       SECURITY_ATTRIBUTES sa;
-       PSECURITY_DESCRIPTOR sd = NULL;
-       SID_IDENTIFIER_AUTHORITY sidAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
-       EXPLICIT_ACCESS ea;
-       PSID sidEveryone = NULL;
-       ACL *acl = NULL;
-       TCHAR errorText[1024];
-
-       // Create a well-known SID for the Everyone group.
-       if(!AllocateAndInitializeSid(&sidAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sidEveryone))
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: AllocateAndInitializeSid failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       // Initialize an EXPLICIT_ACCESS structure for an ACE.
-       // The ACE will allow either Everyone or given user to access pipe
-       ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
-       ea.grfAccessPermissions = (FILE_GENERIC_READ | FILE_GENERIC_WRITE) & ~FILE_CREATE_PIPE_INSTANCE;
-       ea.grfAccessMode = SET_ACCESS;
-       ea.grfInheritance = NO_INHERITANCE;
-       if ((s_config.userId == NULL) || (s_config.userId[0] == 0) || !_tcscmp(s_config.userId, _T("*")))
-       {
-               ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
-               ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
-               ea.Trustee.ptstrName  = (LPTSTR)sidEveryone;
-       }
-       else
-       {
-               ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
-               ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
-               ea.Trustee.ptstrName  = (LPTSTR)s_config.userId;
-               AppAgentWriteLog(2, _T("AppAgentConnector: will allow connections only for user %s"), s_config.userId);
-       }
-
-       // Create a new ACL that contains the new ACEs.
-       if (SetEntriesInAcl(1, &ea, NULL, &acl) != ERROR_SUCCESS)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: SetEntriesInAcl failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
-       if (sd == NULL)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: LocalAlloc failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION))
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: InitializeSecurityDescriptor failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       // Add the ACL to the security descriptor. 
-   if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE))
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: SetSecurityDescriptorDacl failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       TCHAR pipeName[MAX_PATH];
-       _sntprintf(pipeName, MAX_PATH, _T("\\\\.\\pipe\\appagent.%s"), s_config.name);
-       sa.nLength = sizeof(SECURITY_ATTRIBUTES);
-       sa.bInheritHandle = FALSE;
-       sa.lpSecurityDescriptor = sd;
-       s_pipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 8192, 8192, 0, &sa);
-       if (s_pipe == INVALID_HANDLE_VALUE)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: CreateNamedPipe failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-               goto cleanup;
-       }
-
-       AppAgentWriteLog(2, _T("AppAgentConnector: named pipe created, waiting for connection"));
-       int connectErrors = 0;
-       while(!s_stop)
-       {
-               BOOL connected = ConnectNamedPipe(s_pipe, NULL);
-               if (connected || (GetLastError() == ERROR_PIPE_CONNECTED))
-               {
-                       ProcessRequest(s_pipe);
-                       DisconnectNamedPipe(s_pipe);
-                       connectErrors = 0;
-               }
-               else
-               {
-                       AppAgentWriteLog(2, _T("AppAgentConnector: ConnectNamedPipe failed (%s)"), GetSystemErrorText(GetLastError(), errorText, 1024));
-                       connectErrors++;
-                       if (connectErrors > 10)
-                               break;  // Stop this connector if ConnectNamedPipe fails instantly
-               }
-       }
-
-cleanup:
-       if (s_pipe != NULL)
-       {
-               CloseHandle(s_pipe);
-               s_pipe = INVALID_PIPE_HANDLE;
-       }
-
-       if (sd != NULL)
-               LocalFree(sd);
-
-       if (acl != NULL)
-               LocalFree(acl);
-
-       if (sidEveryone != NULL)
-               FreeSid(sidEveryone);
-
-       AppAgentWriteLog(2, _T("AppAgentConnector: listener thread stopped"));
-       return THREAD_OK;
-}
-
-#else
-
-static THREAD_RESULT THREAD_CALL AppAgentConnector(void *arg)
-{
-       mode_t prevMask = 0;
-
-       s_pipe = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (s_pipe == -1)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: socket failed (%s)"), _tcserror(errno));
-               goto cleanup;
-       }
-       
-       struct sockaddr_un addrLocal;
-       addrLocal.sun_family = AF_UNIX;
-#ifdef UNICODE
-   sprintf(addrLocal.sun_path, "/tmp/.appagent.%S", s_config.name);
-#else
-       sprintf(addrLocal.sun_path, "/tmp/.appagent.%s", s_config.name);
-#endif
-       unlink(addrLocal.sun_path);
-       prevMask = umask(S_IWGRP | S_IWOTH);
-       if (bind(s_pipe, (struct sockaddr *)&addrLocal, SUN_LEN(&addrLocal)) == -1)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: bind failed (%s)"), _tcserror(errno));
-               umask(prevMask);
-               goto cleanup;
-       }
-       umask(prevMask);
-
-       if (listen(s_pipe, 5) == -1)
-       {
-               AppAgentWriteLog(2, _T("AppAgentConnector: listen failed (%s)"), _tcserror(errno));
-               goto cleanup;
-       }
-       
-       while(!s_stop)
-       {
-               struct sockaddr_un addrRemote;
-               socklen_t size = sizeof(struct sockaddr_un);
-               SOCKET cs = accept(s_pipe, (struct sockaddr *)&addrRemote, &size);
-               if (cs > 0)
-               {
-                       ProcessRequest(cs);
-                       shutdown(cs, 2);
-                       close(cs);
-               }
-               else
-               {
-                       AppAgentWriteLog(2, _T("AppAgentConnector: accept failed (%s)"), _tcserror(errno));
-               }
-       }
-
-cleanup:
-       if (s_pipe != -1)
-       {
-               close(s_pipe);
-               s_pipe = INVALID_PIPE_HANDLE;
-       }
-
-       AppAgentWriteLog(2, _T("AppAgentConnector: listener thread stopped"));
-       return THREAD_OK;
-}
-
-#endif
-
 #if defined(_AIX) || defined(__sun)
 
 /**
@@ -389,12 +200,23 @@ bool APPAGENT_EXPORTABLE AppAgentInit(APPAGENT_INIT *initData)
 }
 
 /**
+ * Pipe listener
+ */
+static NamedPipeListener *s_listener = NULL;
+
+/**
  * Start application agent
  */
 void APPAGENT_EXPORTABLE AppAgentStart()
 {
-       if ((s_initialized) && (s_connectorThread == INVALID_THREAD_HANDLE))
-               s_connectorThread = ThreadCreateEx(AppAgentConnector, 0, NULL);
+   if (!s_initialized || (s_listener != NULL))
+      return;
+
+   TCHAR name[64];
+   _sntprintf(name, 64, _T("appagent.%s"), s_config.name);
+   s_listener = NamedPipeListener::create(name, ProcessRequest, NULL, s_config.userId);
+   if (s_listener != NULL)
+      s_listener->start();
 }
 
 /**
@@ -402,23 +224,10 @@ void APPAGENT_EXPORTABLE AppAgentStart()
  */
 void APPAGENT_EXPORTABLE AppAgentStop()
 {
-       if (s_initialized && (s_connectorThread != INVALID_THREAD_HANDLE))
+       if (s_initialized && (s_listener != NULL))
        {
-               s_stop = true;
-               if (s_pipe != INVALID_THREAD_HANDLE)
-               {
-#ifdef _WIN32
-                       CloseHandle(s_pipe);
-#else
-                       shutdown(s_pipe, SHUT_RDWR);
-#if defined(_AIX) || defined(__sun)
-         pthread_kill(s_connectorThread, SIGUSR2);
-#endif
-#endif
-                       s_pipe = INVALID_PIPE_HANDLE;
-               }
-               ThreadJoin(s_connectorThread);
-               s_connectorThread = INVALID_THREAD_HANDLE;
+          s_listener->stop();
+          delete_and_null(s_listener);
        }
 }