Fixed typo mistake
[public/netxms.git] / include / nxcpapi.h
CommitLineData
9fa031cd 1/*
0d9c1b96 2** NetXMS - Network Management System
9f2ad16c 3** NXCP API
68f384ea 4** Copyright (C) 2003-2010 Victor Kirhenshtein
0d9c1b96
VK
5**
6** This program is free software; you can redistribute it and/or modify
65d2c384
VK
7** it under the terms of the GNU Lesser General Public License as published by
8** the Free Software Foundation; either version 3 of the License, or
0d9c1b96
VK
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
68f384ea 16** You should have received a copy of the GNU Lesser General Public License
0d9c1b96
VK
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
9f2ad16c 20** File: nxcpapi.h
0d9c1b96
VK
21**
22**/
23
9f2ad16c
VK
24#ifndef _nxcpapi_h_
25#define _nxcpapi_h_
0d9c1b96 26
9f2ad16c 27#include <nms_util.h>
bf6fb6c3 28#include <nms_threads.h>
de4af576 29#include <uuid.h>
8c290af0 30
bb8136f7
VK
31#ifdef _WIN32
32#include <wincrypt.h>
33#endif
34
4af351c7 35/**
b368969c 36 * Temporary buffer structure for RecvNXCPMessage() function
4af351c7 37 */
0d9c1b96
VK
38typedef struct
39{
b368969c
VK
40 UINT32 bufferSize;
41 UINT32 bufferPos;
43a6f3ca 42 char buffer[NXCP_TEMP_BUF_SIZE];
b368969c 43} NXCP_BUFFER;
0d9c1b96
VK
44
45
9f2ad16c
VK
46#ifdef __cplusplus
47
5c44534b
VK
48struct MessageField;
49
4af351c7
VK
50/**
51 * Parsed NXCP message
52 */
b368969c 53class LIBNETXMS_EXPORTABLE NXCPMessage
0d9c1b96
VK
54{
55private:
b368969c
VK
56 UINT16 m_code;
57 UINT16 m_flags;
5c44534b 58 UINT32 m_id;
6be0a20b
VK
59 MessageField *m_fields; // Message fields
60 int m_version; // Protocol version
61 BYTE *m_data; // binary data
62 size_t m_dataSize; // binary data size
0d9c1b96 63
712b2760 64 void *set(UINT32 fieldId, BYTE type, const void *value, bool isSigned = false, size_t size = 0);
8f238fd7 65 void *get(UINT32 fieldId, BYTE requiredType, BYTE *fieldType = NULL);
b368969c 66 NXCP_MESSAGE_FIELD *find(UINT32 fieldId);
0d9c1b96
VK
67
68public:
b368969c
VK
69 NXCPMessage(int version = NXCP_VERSION);
70 NXCPMessage(NXCPMessage *msg);
71 NXCPMessage(NXCP_MESSAGE *rawMag, int version = NXCP_VERSION);
72 ~NXCPMessage();
0d9c1b96 73
b368969c 74 NXCP_MESSAGE *createMessage();
0d9c1b96 75
b368969c
VK
76 UINT16 getCode() { return m_code; }
77 void setCode(UINT16 code) { m_code = code; }
0d9c1b96 78
b368969c
VK
79 UINT32 getId() { return m_id; }
80 void setId(UINT32 id) { m_id = id; }
0d9c1b96 81
6be0a20b 82 bool isEndOfFile() { return (m_flags & MF_END_OF_FILE) ? true : false; }
5c44534b
VK
83 bool isEndOfSequence() { return (m_flags & MF_END_OF_SEQUENCE) ? true : false; }
84 bool isReverseOrder() { return (m_flags & MF_REVERSE_ORDER) ? true : false; }
6be0a20b
VK
85 bool isBinary() { return (m_flags & MF_BINARY) ? true : false; }
86
87 BYTE *getBinaryData() { return m_data; }
88 size_t getBinaryDataSize() { return m_dataSize; }
4af351c7 89
4101571e
VK
90 bool isFieldExist(UINT32 fieldId) { return find(fieldId) != NULL; }
91 int getFieldType(UINT32 fieldId);
92
712b2760
VK
93 void setField(UINT32 fieldId, INT16 value) { set(fieldId, NXCP_DT_INT16, &value, true); }
94 void setField(UINT32 fieldId, UINT16 value) { set(fieldId, NXCP_DT_INT16, &value, false); }
95 void setField(UINT32 fieldId, INT32 value) { set(fieldId, NXCP_DT_INT32, &value, true); }
96 void setField(UINT32 fieldId, UINT32 value) { set(fieldId, NXCP_DT_INT32, &value, false); }
97 void setField(UINT32 fieldId, INT64 value) { set(fieldId, NXCP_DT_INT64, &value, true); }
98 void setField(UINT32 fieldId, UINT64 value) { set(fieldId, NXCP_DT_INT64, &value, false); }
b368969c
VK
99 void setField(UINT32 fieldId, double value) { set(fieldId, NXCP_DT_FLOAT, &value); }
100 void setField(UINT32 fieldId, const TCHAR *value) { if (value != NULL) set(fieldId, NXCP_DT_STRING, value); }
712b2760 101 void setField(UINT32 fieldId, const TCHAR *value, size_t maxLen) { if (value != NULL) set(fieldId, NXCP_DT_STRING, value, false, maxLen); }
5f573844 102 void setField(UINT32 fieldId, const BYTE *value, size_t size) { set(fieldId, NXCP_DT_BINARY, value, false, size); }
de4af576
VK
103 void setField(UINT32 fieldId, const InetAddress& value) { set(fieldId, NXCP_DT_INETADDR, &value); }
104 void setField(UINT32 fieldId, const uuid& value) { set(fieldId, NXCP_DT_BINARY, value.getValue(), false, UUID_LENGTH); }
35f836fe 105#ifdef UNICODE
b368969c 106 void setFieldFromMBString(UINT32 fieldId, const char *value);
35f836fe 107#else
b368969c 108 void setFieldFromMBString(UINT32 fieldId, const char *value) { set(fieldId, NXCP_DT_STRING, value); }
35f836fe 109#endif
b368969c 110 void setFieldFromTime(UINT32 fieldId, time_t value) { UINT64 t = (UINT64)value; set(fieldId, NXCP_DT_INT64, &t); }
14149881 111 void setFieldFromInt32Array(UINT32 fieldId, size_t numElements, const UINT32 *elements);
b368969c 112 void setFieldFromInt32Array(UINT32 fieldId, IntegerArray<UINT32> *data);
8f238fd7 113 bool setFieldFromFile(UINT32 fieldId, const TCHAR *pszFileName);
967893bb 114
4101571e 115 INT16 getFieldAsInt16(UINT32 fieldId);
b368969c 116 UINT16 getFieldAsUInt16(UINT32 fieldId);
4101571e 117 INT32 getFieldAsInt32(UINT32 fieldId);
b368969c 118 UINT32 getFieldAsUInt32(UINT32 fieldId);
4101571e 119 INT64 getFieldAsInt64(UINT32 fieldId);
b368969c 120 UINT64 getFieldAsUInt64(UINT32 fieldId);
4101571e 121 double getFieldAsDouble(UINT32 fieldId);
d6bbfa4e 122 bool getFieldAsBoolean(UINT32 fieldId);
8f238fd7 123 time_t getFieldAsTime(UINT32 fieldId);
9a68ca24
VK
124 UINT32 getFieldAsInt32Array(UINT32 fieldId, UINT32 numElements, UINT32 *buffer);
125 UINT32 getFieldAsInt32Array(UINT32 fieldId, IntegerArray<UINT32> *data);
ac14e3e6 126 BYTE *getBinaryFieldPtr(UINT32 fieldId, size_t *size);
b368969c
VK
127 TCHAR *getFieldAsString(UINT32 fieldId, TCHAR *buffer = NULL, size_t bufferSize = 0);
128 char *getFieldAsMBString(UINT32 fieldId, char *buffer = NULL, size_t bufferSize = 0);
129 char *getFieldAsUtf8String(UINT32 fieldId, char *buffer = NULL, size_t bufferSize = 0);
130 UINT32 getFieldAsBinary(UINT32 fieldId, BYTE *buffer, size_t bufferSize);
712b2760 131 InetAddress getFieldAsInetAddress(UINT32 fieldId);
de4af576 132 uuid getFieldAsGUID(UINT32 fieldId);
4101571e 133
b368969c 134 void deleteAllFields();
e44ac467 135
5c44534b
VK
136 void disableEncryption() { m_flags |= MF_DONT_ENCRYPT; }
137 void setEndOfSequence() { m_flags |= MF_END_OF_SEQUENCE; }
138 void setReverseOrderFlag() { m_flags |= MF_REVERSE_ORDER; }
934f53da 139
b368969c 140 static String dump(NXCP_MESSAGE *msg, int version);
0d9c1b96
VK
141};
142
4af351c7
VK
143/**
144 * Message waiting queue element structure
145 */
deaa4491
VK
146typedef struct
147{
b368969c 148 void *msg; // Pointer to message, either to NXCPMessage object or raw message
14149881 149 UINT64 sequence; // Sequence number
f128c07c
VK
150 UINT32 id; // Message ID
151 UINT32 ttl; // Message time-to-live in milliseconds
152 UINT16 code; // Message code
153 UINT16 isBinary; // 1 for binary (raw) messages
deaa4491
VK
154} WAIT_QUEUE_ELEMENT;
155
4af351c7 156/**
f128c07c
VK
157 * Max number of waiting threads in message queue
158 */
159#define MAX_MSGQUEUE_WAITERS 32
160
161/**
4af351c7
VK
162 * Message waiting queue class
163 */
9f2ad16c 164class LIBNETXMS_EXPORTABLE MsgWaitQueue
deaa4491 165{
deaa4491 166private:
f128c07c
VK
167#ifdef _WIN32
168 CRITICAL_SECTION m_mutex;
169 HANDLE m_wakeupEvents[MAX_MSGQUEUE_WAITERS];
170 BYTE m_waiters[MAX_MSGQUEUE_WAITERS];
171#else
172 pthread_mutex_t m_mutex;
173 pthread_cond_t m_wakeupCondition;
174#endif
f128c07c
VK
175 UINT32 m_holdTime;
176 int m_size;
177 int m_allocated;
178 WAIT_QUEUE_ELEMENT *m_elements;
14149881 179 UINT64 m_sequence;
deaa4491 180
f128c07c
VK
181 void *waitForMessageInternal(UINT16 isBinary, UINT16 code, UINT32 id, UINT32 timeout);
182
183 void lock()
184 {
185#ifdef _WIN32
186 EnterCriticalSection(&m_mutex);
187#else
188 pthread_mutex_lock(&m_mutex);
189#endif
190 }
191
192 void unlock()
193 {
194#ifdef _WIN32
195 LeaveCriticalSection(&m_mutex);
196#else
197 pthread_mutex_unlock(&m_mutex);
198#endif
199 }
cc022855 200
d87ddcc2
VK
201 void housekeeperRun();
202
203 static MUTEX m_housekeeperLock;
204 static HashMap<UINT64, MsgWaitQueue> *m_activeQueues;
205 static CONDITION m_shutdownCondition;
206 static THREAD m_housekeeperThread;
207 static EnumerationCallbackResult houseKeeperCallback(const void *key, const void *object, void *arg);
208 static THREAD_RESULT THREAD_CALL housekeeperThread(void *);
209 static EnumerationCallbackResult diagInfoCallback(const void *key, const void *object, void *arg);
deaa4491
VK
210
211public:
212 MsgWaitQueue();
213 ~MsgWaitQueue();
214
b368969c
VK
215 void put(NXCPMessage *pMsg);
216 void put(NXCP_MESSAGE *pMsg);
217 NXCPMessage *waitForMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 218 {
b368969c 219 return (NXCPMessage *)waitForMessageInternal(0, wCode, dwId, dwTimeOut);
deaa4491 220 }
b368969c 221 NXCP_MESSAGE *waitForRawMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 222 {
b368969c 223 return (NXCP_MESSAGE *)waitForMessageInternal(1, wCode, dwId, dwTimeOut);
deaa4491 224 }
cc022855 225
c17f6cbc 226 void clear();
f128c07c 227 void setHoldTime(UINT32 holdTime) { m_holdTime = holdTime; }
d87ddcc2
VK
228
229 static void shutdown();
230 static String getDiagInfo();
deaa4491
VK
231};
232
b549a0f8
VK
233/**
234 * NXCP encryption context
235 */
98abc9f1
VK
236class LIBNETXMS_EXPORTABLE NXCPEncryptionContext : public RefCountObject
237{
238private:
239 int m_cipher;
240 BYTE *m_sessionKey;
241 int m_keyLength;
242 BYTE m_iv[EVP_MAX_IV_LENGTH];
e4e091f0 243#ifdef _WITH_ENCRYPTION
e6336a90
VK
244 EVP_CIPHER_CTX m_encryptor;
245 EVP_CIPHER_CTX m_decryptor;
db05c2af 246 MUTEX m_encryptorLock;
e4e091f0 247#endif
98abc9f1
VK
248
249 NXCPEncryptionContext();
e6336a90 250 bool initCipher(int cipher);
98abc9f1
VK
251
252public:
b368969c 253 static NXCPEncryptionContext *create(NXCPMessage *msg, RSA *privateKey);
967893bb 254 static NXCPEncryptionContext *create(UINT32 ciphers);
98abc9f1
VK
255
256 virtual ~NXCPEncryptionContext();
257
b368969c 258 NXCP_ENCRYPTED_MESSAGE *encryptMessage(NXCP_MESSAGE *msg);
6be0a20b 259 bool decryptMessage(NXCP_ENCRYPTED_MESSAGE *msg, BYTE *decryptionBuffer);
e6336a90 260
98abc9f1
VK
261 int getCipher() { return m_cipher; }
262 BYTE *getSessionKey() { return m_sessionKey; }
263 int getKeyLength() { return m_keyLength; }
264 BYTE *getIV() { return m_iv; }
265};
266
6be0a20b
VK
267/**
268 * Message receiver result codes
269 */
270enum MessageReceiverResult
271{
272 MSGRECV_SUCCESS = 0,
273 MSGRECV_CLOSED = 1,
274 MSGRECV_TIMEOUT = 2,
275 MSGRECV_COMM_FAILURE = 3,
276 MSGRECV_DECRYPTION_FAILURE = 4
277};
278
279/**
280 * Message receiver - abstract base class
281 */
282class LIBNETXMS_EXPORTABLE AbstractMessageReceiver
283{
284private:
285 BYTE *m_buffer;
286 BYTE *m_decryptionBuffer;
287 NXCPEncryptionContext *m_encryptionContext;
288 size_t m_initialSize;
289 size_t m_size;
290 size_t m_maxSize;
291 size_t m_dataSize;
292 size_t m_bytesToSkip;
293
b368969c 294 NXCPMessage *getMessageFromBuffer();
6be0a20b
VK
295
296protected:
297 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout) = 0;
298
299public:
300 AbstractMessageReceiver(size_t initialSize, size_t maxSize);
301 virtual ~AbstractMessageReceiver();
302
303 void setEncryptionContext(NXCPEncryptionContext *ctx) { m_encryptionContext = ctx; }
304
b368969c
VK
305 NXCPMessage *readMessage(UINT32 timeout, MessageReceiverResult *result);
306 NXCP_MESSAGE *getRawMessageBuffer() { return (NXCP_MESSAGE *)m_buffer; }
307
308 static const TCHAR *resultToText(MessageReceiverResult result);
6be0a20b
VK
309};
310
311/**
312 * Message receiver - socket implementation
313 */
314class LIBNETXMS_EXPORTABLE SocketMessageReceiver : public AbstractMessageReceiver
315{
316private:
317 SOCKET m_socket;
318
319protected:
320 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
321
322public:
323 SocketMessageReceiver(SOCKET socket, size_t initialSize, size_t maxSize);
324 virtual ~SocketMessageReceiver();
325};
326
327/**
328 * Message receiver - UNIX socket/named pipe implementation
329 */
330class LIBNETXMS_EXPORTABLE PipeMessageReceiver : public AbstractMessageReceiver
331{
332private:
333 HPIPE m_pipe;
334#ifdef _WIN32
335 HANDLE m_readEvent;
336#endif
337
338protected:
339 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
340
341public:
342 PipeMessageReceiver(HPIPE pipe, size_t initialSize, size_t maxSize);
343 virtual ~PipeMessageReceiver();
344};
345
503da871
VK
346/**
347 * NXCP compression methods
348 */
349enum NXCPCompressionMethod
350{
351 NXCP_COMPRESSION_NONE = 0,
352 NXCP_COMPRESSION_LZ4 = 1
353};
354
355/**
356 * Abstract stream compressor
357 */
358class LIBNETXMS_EXPORTABLE StreamCompressor
359{
360public:
9757ca46
VK
361 virtual ~StreamCompressor();
362
503da871
VK
363 virtual size_t compress(const BYTE *in, size_t inSize, BYTE *out, size_t maxOutSize) = 0;
364 virtual size_t decompress(const BYTE *in, size_t inSize, const BYTE **out) = 0;
365 virtual size_t compressBufferSize(size_t dataSize) = 0;
366
367 static StreamCompressor *create(NXCPCompressionMethod method, bool compress, size_t maxBlockSize);
368};
369
370/**
371 * Dummy stream compressor
372 */
373class LIBNETXMS_EXPORTABLE DummyStreamCompressor : public StreamCompressor
374{
375public:
9757ca46
VK
376 virtual ~DummyStreamCompressor();
377
503da871
VK
378 virtual size_t compress(const BYTE *in, size_t inSize, BYTE *out, size_t maxOutSize);
379 virtual size_t decompress(const BYTE *in, size_t inSize, const BYTE **out);
380 virtual size_t compressBufferSize(size_t dataSize);
381};
382
383struct __LZ4_stream_t;
384struct __LZ4_streamDecode_t;
385
386/**
387 * LZ4 stream compressor
388 */
389class LIBNETXMS_EXPORTABLE LZ4StreamCompressor : public StreamCompressor
390{
391private:
392 union
393 {
394 __LZ4_stream_t *encoder;
395 __LZ4_streamDecode_t *decoder;
396 } m_stream;
397 char *m_buffer;
398 size_t m_maxBlockSize;
399 size_t m_bufferSize;
400 size_t m_bufferPos;
401 bool m_compress;
402
403public:
404 LZ4StreamCompressor(bool compress, size_t maxBlockSize);
405 virtual ~LZ4StreamCompressor();
406
407 virtual size_t compress(const BYTE *in, size_t inSize, BYTE *out, size_t maxOutSize);
408 virtual size_t decompress(const BYTE *in, size_t inSize, const BYTE **out);
409 virtual size_t compressBufferSize(size_t dataSize);
410};
411
208d7427
VK
412#if 0
413/**
414 * NXCP message consumer interface
415 */
416class LIBNETXMS_EXPORTABLE MessageConsumer
417{
418public:
419 virtual SOCKET getSocket() = 0;
420 virtual void processMessage(NXCPMessage *msg) = 0;
421};
422
423/**
424 * Socket receiver - manages receiving NXCP messages from multiple sockets
425 */
426class LIBNETXMS_EXPORTABLE SocketReceiver
427{
428private:
429 THREAD m_thread;
430 HashMap<SOCKET, MessageConsumer> *m_consumers;
431
432 static int m_maxSocketsPerThread;
433 static ObjectArray<SocketReceiver> *m_receivers;
434
435public:
436 static void start();
437 static void shutdown();
438
439 static void addConsumer(MessageConsumer *mc);
440 static void removeConsumer(MessageConsumer *mc);
441
442 static String getDiagInfo();
443};
444#endif
445
9f2ad16c
VK
446#else /* __cplusplus */
447
b368969c 448typedef void NXCPMessage;
98abc9f1 449typedef void NXCPEncryptionContext;
9f2ad16c
VK
450
451#endif
452
deaa4491
VK
453
454//
0d9c1b96
VK
455// Functions
456//
457
458#ifdef __cplusplus
0d9c1b96 459
b368969c
VK
460int LIBNETXMS_EXPORTABLE RecvNXCPMessage(SOCKET hSocket, NXCP_MESSAGE *pMsg,
461 NXCP_BUFFER *pBuffer, UINT32 dwMaxMsgSize,
98abc9f1 462 NXCPEncryptionContext **ppCtx,
967893bb 463 BYTE *pDecryptionBuffer, UINT32 dwTimeout);
b368969c
VK
464int LIBNETXMS_EXPORTABLE RecvNXCPMessageEx(SOCKET hSocket, NXCP_MESSAGE **msgBuffer,
465 NXCP_BUFFER *nxcpBuffer, UINT32 *bufferSize,
cc022855 466 NXCPEncryptionContext **ppCtx,
967893bb
VK
467 BYTE **decryptionBuffer, UINT32 dwTimeout,
468 UINT32 maxMsgSize);
b368969c 469NXCP_MESSAGE LIBNETXMS_EXPORTABLE *CreateRawNXCPMessage(WORD wCode, UINT32 dwId, WORD flags,
967893bb 470 UINT32 dwDataSize, void *pData,
b368969c
VK
471 NXCP_MESSAGE *pBuffer);
472TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD wCode, TCHAR *buffer);
967893bb 473BOOL LIBNETXMS_EXPORTABLE SendFileOverNXCP(SOCKET hSocket, UINT32 dwId, const TCHAR *pszFile,
cc022855 474 NXCPEncryptionContext *pCtx, long offset,
7b8b337e 475 void (* progressCallback)(INT64, void *), void *cbArg,
503da871 476 MUTEX mutex, NXCPCompressionMethod compressionMethod = NXCP_COMPRESSION_NONE);
7b8b337e 477BOOL LIBNETXMS_EXPORTABLE NXCPGetPeerProtocolVersion(SOCKET hSocket, int *pnVersion, MUTEX mutex);
cc022855 478
bf6fb6c3 479bool LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCallback)(int, const TCHAR *, va_list args));
e5390fb5
VK
480UINT32 LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphers();
481String LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphersAsText();
b368969c 482NXCP_ENCRYPTED_MESSAGE LIBNETXMS_EXPORTABLE *NXCPEncryptMessage(NXCPEncryptionContext *pCtx, NXCP_MESSAGE *pMsg);
bf6fb6c3 483bool LIBNETXMS_EXPORTABLE NXCPDecryptMessage(NXCPEncryptionContext *pCtx,
6be0a20b 484 NXCP_ENCRYPTED_MESSAGE *pMsg,
e44ac467 485 BYTE *pDecryptionBuffer);
b368969c 486UINT32 LIBNETXMS_EXPORTABLE SetupEncryptionContext(NXCPMessage *pMsg,
98abc9f1 487 NXCPEncryptionContext **ppCtx,
b368969c 488 NXCPMessage **ppResponse,
4bd3d6c5 489 RSA *pPrivateKey, int nNXCPVersion);
b368969c 490void LIBNETXMS_EXPORTABLE PrepareKeyRequestMsg(NXCPMessage *pMsg, RSA *pServerKey, bool useX509Format);
3aa0061c 491RSA LIBNETXMS_EXPORTABLE *LoadRSAKeys(const TCHAR *pszKeyFile);
15cf5acc 492
bb8136f7 493#ifdef _WIN32
967893bb 494BOOL LIBNETXMS_EXPORTABLE SignMessageWithCAPI(BYTE *pMsg, UINT32 dwMsgLen, const CERT_CONTEXT *pCert,
b368969c 495 BYTE *pBuffer, size_t bufferSize, UINT32 *pdwSigLen);
bb8136f7
VK
496#endif
497
0d9c1b96
VK
498#endif
499
9f2ad16c 500#endif /* _nxcpapi_h_ */