/* 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 #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, 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 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 that was earlier passed to K2Cli_Initialize(...), 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);