implemented helper class SocketListener; server listeners converted to use SocketListener
[public/netxms.git] / src / server / core / mdconn.cpp
CommitLineData
534e1b83
VK
1/*
2** NetXMS - Network Management System
f0718805 3** Copyright (C) 2003-2017 Victor Kirhenshtein
534e1b83
VK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** File: mdconn.cpp
20**
21**/
22
23#include "nxcore.h"
f0718805 24#include <socket_listener.h>
534e1b83
VK
25
26/**
534e1b83
VK
27 * Static data
28 */
f0718805
VK
29static MobileDeviceSession *s_sessionList[MAX_DEVICE_SESSIONS];
30static RWLOCK s_sessionListLock;
534e1b83
VK
31
32/**
33 * Register new session in list
34 */
35static BOOL RegisterMobileDeviceSession(MobileDeviceSession *pSession)
36{
f0718805
VK
37 RWLockWriteLock(s_sessionListLock, INFINITE);
38 for(int i = 0; i < MAX_DEVICE_SESSIONS; i++)
39 if (s_sessionList[i] == NULL)
534e1b83 40 {
f0718805 41 s_sessionList[i] = pSession;
2a964810 42 pSession->setId(i + MAX_CLIENT_SESSIONS);
f0718805 43 RWLockUnlock(s_sessionListLock);
534e1b83
VK
44 return TRUE;
45 }
46
f0718805 47 RWLockUnlock(s_sessionListLock);
534e1b83
VK
48 nxlog_write(MSG_TOO_MANY_MD_SESSIONS, EVENTLOG_WARNING_TYPE, NULL);
49 return FALSE;
50}
51
52/**
53 * Unregister session
54 */
2a964810 55void UnregisterMobileDeviceSession(int id)
534e1b83 56{
f0718805
VK
57 RWLockWriteLock(s_sessionListLock, INFINITE);
58 s_sessionList[id - MAX_CLIENT_SESSIONS] = NULL;
59 RWLockUnlock(s_sessionListLock);
534e1b83
VK
60}
61
62/**
63 * Initialize mobile device listener(s)
64 */
65void InitMobileDeviceListeners()
66{
f0718805
VK
67 memset(s_sessionList, 0, sizeof(s_sessionList));
68 s_sessionListLock = RWLockCreate();
534e1b83
VK
69}
70
71/**
f0718805 72 * Mobile device listener class
534e1b83 73 */
f0718805 74class MobileDeviceListener : public SocketListener
534e1b83 75{
f0718805
VK
76protected:
77 virtual ConnectionProcessingResult processConnection(SOCKET s, const InetAddress& peer);
78 virtual bool isStopConditionReached();
534e1b83 79
f0718805
VK
80public:
81 MobileDeviceListener(UINT16 port) : SocketListener(port) { setName(_T("MobileDevices")); }
82};
534e1b83 83
f0718805
VK
84/**
85 * Listener stop condition
86 */
87bool MobileDeviceListener::isStopConditionReached()
88{
89 return IsShutdownInProgress();
90}
534e1b83 91
f0718805
VK
92/**
93 * Process incoming connection
94 */
95ConnectionProcessingResult MobileDeviceListener::processConnection(SOCKET s, const InetAddress& peer)
96{
97 SetSocketNonBlocking(s);
98 MobileDeviceSession *session = new MobileDeviceSession(s, peer);
99 if (RegisterMobileDeviceSession(session))
534e1b83 100 {
f0718805 101 session->run();
534e1b83 102 }
f0718805 103 else
534e1b83 104 {
f0718805 105 delete session;
534e1b83 106 }
f0718805 107 return CPR_BACKGROUND;
534e1b83
VK
108}
109
110/**
f0718805 111 * Listener thread
534e1b83 112 */
f0718805 113THREAD_RESULT THREAD_CALL MobileDeviceListenerThread(void *arg)
534e1b83 114{
f0718805
VK
115 UINT16 listenPort = (UINT16)ConfigReadInt(_T("MobileDeviceListenerPort"), SERVER_LISTEN_PORT_FOR_MOBILES);
116 MobileDeviceListener listener(listenPort);
117 listener.setListenAddress(g_szListenAddress);
118 if (!listener.initialize())
534e1b83 119 return THREAD_OK;
534e1b83 120
f0718805
VK
121 listener.mainLoop();
122 listener.shutdown();
534e1b83
VK
123 return THREAD_OK;
124}
125
534e1b83
VK
126/**
127 * Dump client sessions to screen
128 */
129void DumpMobileDeviceSessions(CONSOLE_CTX pCtx)
130{
131 int i, iCount;
132 TCHAR szBuffer[256];
133 static const TCHAR *pszStateName[] = { _T("init"), _T("idle"), _T("processing") };
134 static const TCHAR *pszCipherName[] = { _T("NONE"), _T("AES-256"), _T("BLOWFISH"), _T("IDEA"), _T("3DES"), _T("AES-128") };
135
136 ConsolePrintf(pCtx, _T("ID STATE CIPHER USER [CLIENT]\n"));
f0718805 137 RWLockReadLock(s_sessionListLock, INFINITE);
534e1b83 138 for(i = 0, iCount = 0; i < MAX_DEVICE_SESSIONS; i++)
f0718805 139 if (s_sessionList[i] != NULL)
534e1b83
VK
140 {
141 ConsolePrintf(pCtx, _T("%-3d %-24s %-8s %s [%s]\n"), i,
f0718805
VK
142 (s_sessionList[i]->getState() != SESSION_STATE_PROCESSING) ?
143 pszStateName[s_sessionList[i]->getState()] :
144 NXCPMessageCodeName(s_sessionList[i]->getCurrentCmd(), szBuffer),
145 pszCipherName[s_sessionList[i]->getCipher() + 1],
146 s_sessionList[i]->getUserName(),
147 s_sessionList[i]->getClientInfo());
534e1b83
VK
148 iCount++;
149 }
f0718805 150 RWLockUnlock(s_sessionListLock);
534e1b83
VK
151 ConsolePrintf(pCtx, _T("\n%d active session%s\n\n"), iCount, iCount == 1 ? _T("") : _T("s"));
152}