182 lines
7.2 KiB
C
182 lines
7.2 KiB
C
|
|
/*
|
||
|
|
Copyright (c) 2013, 2014 IOnU Security Inc. All rights reserved
|
||
|
|
Created August 2013 by Kendrick Webster
|
||
|
|
|
||
|
|
K2Client.h - header for platform-agnostic communications driver
|
||
|
|
layer of K2 socket notifier UDP client library
|
||
|
|
|
||
|
|
The K2 socket notifier UDP client establishes a connection with
|
||
|
|
a K2 daemon. The connection is established and maintained by
|
||
|
|
sending a UDP 'connect' packet once at startup and then repeatedly
|
||
|
|
thereafter at the hearbeat timer interval. The daemon may send
|
||
|
|
a notification packet to the client at any time.
|
||
|
|
|
||
|
|
This module contains platform-agnostic code to implement the UDP
|
||
|
|
protocol for communicating with the daemon. Platform-specific code
|
||
|
|
is responsible for calling the following functions under the
|
||
|
|
following conditions:
|
||
|
|
|
||
|
|
Function Condition
|
||
|
|
-----------------------------------------------------------------------
|
||
|
|
K2Cli_Initialize At startup or to change parameters
|
||
|
|
K2Cli_HandlePacket UDP datagram arrived
|
||
|
|
K2Cli_Timer Call at aprx K2CLI_TIMER_TICKS_PER_SECOND rate
|
||
|
|
K2Cli_Logout Closes connection
|
||
|
|
K2Cli_Login Opens connection
|
||
|
|
K2Cli_StatusSelect Specifies a list of offices for device status
|
||
|
|
|
||
|
|
Platform and application specific code must supply the following
|
||
|
|
callbacks (registered via K2Cli_Initialize(...)):
|
||
|
|
|
||
|
|
Callback Condition
|
||
|
|
-----------------------------------------------------------------------
|
||
|
|
onMessage A message has been received from the server
|
||
|
|
onEvent An event or error occurred
|
||
|
|
onDeviceStatus A device in a subscribed office changed status
|
||
|
|
sendUDP A datagram needs to be sent to the server
|
||
|
|
stopwatch Measure elapsed seconds
|
||
|
|
|
||
|
|
This module is single-threaded. All functions must be called (and all
|
||
|
|
callbacks will be called) from the same thread.
|
||
|
|
*/
|
||
|
|
#pragma once
|
||
|
|
#include <stdint.h>
|
||
|
|
#include "Hash.h"
|
||
|
|
|
||
|
|
#define K2CLI_TIMER_TICKS_PER_SECOND 10
|
||
|
|
|
||
|
|
/* -------------- callback types ---------------- */
|
||
|
|
/*
|
||
|
|
callback for handling messages arriving from the daemon,
|
||
|
|
info points to a NUL-terminated string containing a copy of the 'info'
|
||
|
|
field from the MongoDB queue on the server
|
||
|
|
*/
|
||
|
|
typedef void (* k2cli_message_callback_t)(const char* info);
|
||
|
|
|
||
|
|
/*
|
||
|
|
callback for notification of errors, warnings, and events
|
||
|
|
*/
|
||
|
|
#define K2CLI_EVENTS_EXTRACT // for awk script
|
||
|
|
#define K2CLI_EVENTS \
|
||
|
|
X(K2CLI_INFO_LOGGED_IN, "logged in") \
|
||
|
|
X(K2CLI_INFO_LOGGED_OUT, "logged out") /* daemon acknowledged a logout */ \
|
||
|
|
X(K2CLI_INFO_HEARTBEAT, "heartbeat") \
|
||
|
|
X(K2CLI_INFO_POLL_REQUESTED, "database poll requested") \
|
||
|
|
X(K2CLI_INFO_OFFICES_SUBSCRIBED, "status subscription registered") \
|
||
|
|
X(K2CLI_INFO_SPURIOUS_PACKET, "spurious packet") /* i.e. from a port-scanner, etc. */ \
|
||
|
|
X(K2CLI_INFO_REPEATED_MESSAGE, "received repeated message") /* probably due to a delayed or lost ACK to the daemon */ \
|
||
|
|
X(K2CLI_INFO_REPEATED_ACK, "received repeated ACK") /* probably due to a delayed or lost message to the daemon */ \
|
||
|
|
X(K2CLI_ERROR_NOT_CONNECTED, "ERROR: not connected") \
|
||
|
|
X(K2CLI_ERROR_WRONG_PROTOCOL, "ERROR: wrong protocol version") \
|
||
|
|
X(K2CLI_ERROR_LOGOUT_FAILED, "ERROR: logout failed") \
|
||
|
|
X(K2CLI_ERROR_BAD_OPCODE, "ERROR: unknown opcode in received packet") \
|
||
|
|
X(K2CLI_ERROR_BAD_MSG_SEQUENCE, "ERROR: bad message sequence number") \
|
||
|
|
X(K2CLI_ERROR_BAD_ACK_SEQUENCE, "ERROR: bad ACK sequence number") \
|
||
|
|
X(K2CLI_ERROR_FAILED_ASSERT, "ERROR: failed assert") \
|
||
|
|
X(K2CLI_ERROR_WRONG_URN, "ERROR: wrong URN in received packet") \
|
||
|
|
X(K2CLI_ERROR_MISSING_NUL, "ERROR: missing NUL in received packet") \
|
||
|
|
X(K2CLI_ERROR_DUPLICATE_URN, "ERROR: client URN is already in use")
|
||
|
|
#undef K2CLI_EVENTS_EXTRACT
|
||
|
|
|
||
|
|
enum
|
||
|
|
{
|
||
|
|
#define X(name, text) name,
|
||
|
|
K2CLI_EVENTS
|
||
|
|
#undef X
|
||
|
|
};
|
||
|
|
typedef void (* k2cli_event_callback_t)(unsigned int event);
|
||
|
|
|
||
|
|
/*
|
||
|
|
callback for handling device status notifications from the
|
||
|
|
daemon, status points to a NUL-terminated string indicating
|
||
|
|
device status (see K2IPC_DEVICE_STATUS comments for details)
|
||
|
|
*/
|
||
|
|
typedef void (* k2cli_device_status_callback_t)(const char* status);
|
||
|
|
|
||
|
|
/*
|
||
|
|
callback for handling CPU and memory statistics replies from
|
||
|
|
the daemon, stats points to a NUL-terminated JSON string
|
||
|
|
*/
|
||
|
|
typedef void (* k2cli_stats_callback_t)(const char* stats);
|
||
|
|
|
||
|
|
/*
|
||
|
|
callback for sending UDP packets to the daemon,
|
||
|
|
<len> is the length in bytes (octets) of the data stored in buf,
|
||
|
|
buf was passed to K2Cli_Initialize(...) at startup
|
||
|
|
*/
|
||
|
|
typedef void (* k2cli_udp_send_callback_t)(unsigned int len);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Callback for measuring elapsed time more accurately than counting
|
||
|
|
timer ticks (which can be grossly inaccurate on some platforms).
|
||
|
|
Returns elapsed seconds. Resets if <reset> is non-zero.
|
||
|
|
*/
|
||
|
|
typedef int (* k2cli_stopwatch_callback_t)(int reset);
|
||
|
|
|
||
|
|
|
||
|
|
/* -------------- functions ---------------- */
|
||
|
|
/*
|
||
|
|
Initialize - hooks up callbacks and pointers to data
|
||
|
|
|
||
|
|
buf static (or pre-allocated) packet buffer [K2IPC_MAX_PACKET_SIZE]
|
||
|
|
urn pointer to static string = client's cloudguard URN
|
||
|
|
onMessage message handler callback
|
||
|
|
onEvent error and event reporting callback
|
||
|
|
onDeviceStatus device status notification callback
|
||
|
|
sendUDP UDP datagram sender callback
|
||
|
|
stopwatch callback to measure elapsed time
|
||
|
|
*/
|
||
|
|
void K2Cli_Initialize(
|
||
|
|
uint8_t* buf,
|
||
|
|
const char* urn,
|
||
|
|
k2cli_message_callback_t onMessage,
|
||
|
|
k2cli_event_callback_t onEvent,
|
||
|
|
k2cli_device_status_callback_t onDeviceStatus,
|
||
|
|
k2cli_stats_callback_t onStats,
|
||
|
|
k2cli_udp_send_callback_t sendUDP,
|
||
|
|
k2cli_stopwatch_callback_t stopwatch);
|
||
|
|
|
||
|
|
/*
|
||
|
|
UDP packet handler - call with the packet payload stored in the buffer <buf> that was
|
||
|
|
earlier passed to K2Cli_Initialize(...), <len> is the length of the packet payload.
|
||
|
|
*/
|
||
|
|
void K2Cli_HandlePacket(unsigned int len);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Timer - call at K2CLI_TIMER_TICKS_PER_SECOND rate. Must be called from the same thread
|
||
|
|
that calls any other function in this module (don't call from a *NIX signal handler, etc.)
|
||
|
|
*/
|
||
|
|
void K2Cli_Timer(void);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Logout - triggers a deamon connection close.
|
||
|
|
Closing the connection informs the daemon that this client is offline (sleeping etc.).
|
||
|
|
When the logout handshake is complete, a K2CLI_INFO_LOGGED_OUT event will be reported.
|
||
|
|
*/
|
||
|
|
void K2Cli_Logout(void);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Login - triggers a deamon connection attempt.
|
||
|
|
When the connection is established, a K2CLI_INFO_LOGGED_IN event will be reported.
|
||
|
|
*/
|
||
|
|
void K2Cli_Login(void);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Poll_DB - tells the daemon that the database has updated data
|
||
|
|
(special - used only by the CloudGuard client)
|
||
|
|
*/
|
||
|
|
void K2Cli_Poll_DB(void);
|
||
|
|
|
||
|
|
/*
|
||
|
|
StatusSelect - specifies a comma-delimited list of offices for online/offline
|
||
|
|
device status notifications.
|
||
|
|
*/
|
||
|
|
void K2Cli_StatusSelect(const char* offices);
|
||
|
|
|
||
|
|
/*
|
||
|
|
QueryStats - asks the daemon to return CPU and memory usage statistics,
|
||
|
|
normally results in a call to the onStats callback, but may not if the
|
||
|
|
connection is lost
|
||
|
|
*/
|
||
|
|
void K2Cli_QueryStats(void);
|