summaryrefslogtreecommitdiffstats
path: root/include/ha_msg.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ha_msg.h')
-rw-r--r--include/ha_msg.h464
1 files changed, 464 insertions, 0 deletions
diff --git a/include/ha_msg.h b/include/ha_msg.h
new file mode 100644
index 0000000..fcb6cf6
--- /dev/null
+++ b/include/ha_msg.h
@@ -0,0 +1,464 @@
+/*
+ * Intracluster message object (struct ha_msg)
+ *
+ * Copyright (C) 1999, 2000 Alan Robertson <alanr@unix.sh>
+ * This software licensed under the GNU LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _HA_MSG_H
+# define _HA_MSG_H 1
+#include <stdio.h>
+#include <clplumbing/cl_log.h>
+#include <clplumbing/ipc.h>
+#include <clplumbing/longclock.h>
+#include <clplumbing/cl_uuid.h>
+#include <compress.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+enum cl_netstring_type{
+ FT_STRING = 0,
+ FT_BINARY,
+ FT_STRUCT,
+ FT_LIST,
+ FT_COMPRESS,
+ FT_UNCOMPRESS
+};
+
+enum cl_msgfmt{
+ MSGFMT_NVPAIR,
+ MSGFMT_NETSTRING
+};
+
+
+#define NEEDHEAD 1
+#define NOHEAD 0
+#define HA_MSG_ASSERT(X) do{ if(!(X)){ \
+ cl_log(LOG_ERR, "Assertion failed on line %d in file \"%s\"" \
+ , __LINE__, __FILE__); \
+ abort(); \
+ } \
+ }while(0)
+
+typedef struct hb_msg_stats_s {
+ unsigned long totalmsgs; /* Total # of messages */
+ /* ever handled */
+ unsigned long allocmsgs; /* # Msgs currently allocated */
+ longclock_t lastmsg;
+}hb_msg_stats_t;
+
+struct ha_msg {
+ int nfields;
+ int nalloc;
+ char ** names;
+ size_t* nlens;
+ void ** values;
+ size_t* vlens;
+ int * types;
+};
+
+typedef struct ha_msg HA_Message;
+
+struct fieldtypefuncs_s{
+
+ /* memfree frees the memory involved*/
+ void (*memfree)(void*);
+
+ /* dup makes a complete copy of the field*/
+ void* (*dup)(const void*, size_t);
+
+ /* display printout the field*/
+ void (*display)(int, int, char* , void*, int);
+
+ /* add the field into a message*/
+ int (*addfield) (struct ha_msg* msg, char* name, size_t namelen,
+ void* value, size_t vallen, int depth);
+
+ /* return the string length required to add this field*/
+ int (*stringlen) (size_t namlen, size_t vallen, const void* value);
+
+ /* return the netstring length required to add this field*/
+ int (*netstringlen) (size_t namlen, size_t vallen, const void* value);
+
+ /* print the field into the provided buffer, convert it first */
+ /* if ncecessary*/
+ int (*tostring)(char*, char*, void* ,size_t,int);
+
+ /* print the field into the provided buffer*/
+ int (*tonetstring)(char*, char*, char*, size_t,
+ void*, size_t, int, size_t*);
+
+ /* convert the given string to a field
+ note: this functions involves allocate memory for
+ for the field
+ */
+ int (*stringtofield)(void*, size_t, int depth, void**, size_t* );
+
+ /* convert the given netstring to a field
+ note: this functions involves allocate memory for
+ for the field
+ */
+ int (*netstringtofield)(const void*, size_t, void**, size_t*);
+
+ /* action before packing*/
+ int (*prepackaction)(struct ha_msg* m, int index);
+
+ /* action before a user get the value of a field*/
+ int (*pregetaction)(struct ha_msg* m, int index);
+
+};
+
+#define NUM_MSG_TYPES 6
+extern struct fieldtypefuncs_s fieldtypefuncs[NUM_MSG_TYPES];
+
+#define MSG_NEEDAUTH 0x01
+#define MSG_ALLOWINTR 0X02
+#define MSG_NEEDCOMPRESS 0x04
+#define MSG_NOSIZECHECK 0x08
+
+#define IFACE "!^!\n"
+#define MSG_START ">>>\n"
+#define MSG_END "<<<\n"
+#define MSG_START_NETSTRING "###\n"
+#define MSG_END_NETSTRING "%%%\n"
+#define EQUAL "="
+
+#define MAXDEPTH 16 /* Maximum recursive message depth */
+#define MAXLENGTH 1024
+
+ /* Common field names for our messages */
+#define F_TYPE "t" /* Message type */
+#define F_SUBTYPE "subt" /* Message type */
+#define F_ORIG "src" /* Real Originator */
+#define F_ORIGUUID "srcuuid" /* Real Originator uuid*/
+#define F_NODE "node" /* Node being described */
+#define F_NODELIST "nodelist" /* Node list being described */
+#define F_DELNODELIST "delnodelist" /* Del node list being described */
+#define F_TO "dest" /* Destination (optional) */
+#define F_TOUUID "destuuid" /* Destination uuid(optional) */
+#define F_STATUS "st" /* New status (type = status) */
+#define F_WEIGHT "weight" /* weight of node */
+#define F_SITE "site" /* site of node */
+#define F_PROTOCOL "protocol" /* Protocol number for communication*/
+#define F_CLIENTNAME "cn" /* Client name */
+#define F_CLIENTSTATUS "cs" /* Client status */
+#define F_TIME "ts" /* Timestamp */
+#define F_SEQ "seq" /* Sequence number */
+#define F_LOAD "ld" /* Load average */
+#define F_COMMENT "info" /* Comment */
+#define F_TTL "ttl" /* Time To Live */
+#define F_AUTH "auth" /* Authentication string */
+#define F_HBGENERATION "hg" /* Heartbeat generation number */
+#define F_CLIENT_GENERATION "client_gen" /* client generation number*/
+#define F_FIRSTSEQ "firstseq" /* Lowest seq # to retransmit */
+#define F_LASTSEQ "lastseq" /* Highest seq # to retransmit */
+#define F_RESOURCES "rsc_hold" /* What resources do we hold? */
+#define F_FROMID "from_id" /* from Client id */
+#define F_TOID "to_id" /* To client id */
+#define F_PID "pid" /* PID of client */
+#define F_UID "uid" /* uid of client */
+#define F_GID "gid" /* gid of client */
+#define F_ISSTABLE "isstable" /* true/false for RESOURCES */
+#define F_APIREQ "reqtype" /* API request type for "hbapi" */
+#define F_APIRESULT "result" /* API request result code */
+#define F_IFNAME "ifname" /* Interface name */
+#define F_PNAME "pname" /* Parameter name */
+#define F_PVALUE "pvalue" /* Parameter name */
+#define F_DEADTIME "deadtime" /* Dead time interval in ms. */
+#define F_KEEPALIVE "keepalive" /* Keep alive time interval in ms. */
+#define F_LOGFACILITY "logfacility" /* Suggested cluster syslog facility */
+#define F_NODETYPE "nodetype" /* Type of node */
+#define F_NUMNODES "numnodes" /* num of total nodes(excluding ping nodes*/
+#define F_RTYPE "rtype" /* Resource type */
+#define F_ORDERSEQ "oseq" /* Order Sequence number */
+#define F_DT "dt" /* Dead time field for heartbeat*/
+#define F_ACKSEQ "ackseq" /* The seq number this msg is acking*/
+#define F_CRM_DATA "crm_xml"
+#define F_XML_TAGNAME "__name__"
+#define F_STATE "state" /*used in ccm for state info*/
+
+
+ /* Message types */
+#define T_STATUS "status" /* Status (heartbeat) */
+#define T_IFSTATUS "ifstat" /* Interface status */
+#define T_ASKRESOURCES "ask_resources" /* Let other node ask my resources */
+#define T_ASKRELEASE "ip-request" /* Please give up these resources... */
+#define T_ACKRELEASE "ip-request-resp"/* Resources given up... */
+#define T_QCSTATUS "query-cstatus" /* Query client status */
+#define T_RCSTATUS "respond-cstatus"/* Respond client status */
+#define T_STONITH "stonith" /* Stonith return code */
+#define T_SHUTDONE "shutdone" /* External Shutdown complete */
+#define T_CRM "crmd" /* Cluster resource manager message */
+#define T_ATTRD "attrd" /* Cluster resource manager message */
+#define T_ADDNODE "addnode" /* Add node message*/
+#define T_DELNODE "delnode" /* Delete node message*/
+#define T_SETWEIGHT "setweight" /* Set node weight*/
+#define T_SETSITE "setsite" /* Set node site*/
+#define T_REQNODES "reqnodes" /* Request node list */
+#define T_REPNODES "repnodes" /* reply node list rquest*/
+
+#define T_APIREQ "hbapi-req" /* Heartbeat API request */
+#define T_APIRESP "hbapi-resp" /* Heartbeat API response */
+#define T_APICLISTAT "hbapi-clstat" /* Client status notification" */
+
+#define NOSEQ_PREFIX "NS_" /* PREFIX: Give no sequence number */
+ /* Used for messages which can't be retransmitted */
+ /* Either they're protocol messages or from dumb (ping) endpoints */
+#define T_REXMIT NOSEQ_PREFIX "rexmit" /* Rexmit request */
+#define T_NAKREXMIT NOSEQ_PREFIX "nak_rexmit" /* NAK Rexmit request */
+#define T_NS_STATUS NOSEQ_PREFIX "st" /* ping status */
+#define T_ACKMSG NOSEQ_PREFIX "ackmsg" /* ACK message*/
+
+/* Messages associated with nice_failback */
+#define T_STARTING "starting" /* Starting Heartbeat */
+ /* (requesting resource report) */
+#define T_RESOURCES "resource" /* Resources report */
+
+/* Messages associated with stonith completion results */
+#define T_STONITH_OK "OK" /* stonith completed successfully */
+#define T_STONITH_BADHOST "badhost" /* stonith failed */
+#define T_STONITH_BAD "bad" /* stonith failed */
+#define T_STONITH_NOTCONFGD "n_stnth" /* no stonith device configured */
+#define T_STONITH_UNNEEDED "unneeded" /* STONITH not required */
+
+/* Set up message statistics area */
+
+int netstring_extra(int);
+int cl_msg_stats_add(longclock_t time, int size);
+
+void cl_msg_setstats(volatile hb_msg_stats_t* stats);
+void cl_dump_msgstats(void);
+void cl_set_compression_threshold(size_t threadhold);
+void cl_set_traditional_compression(gboolean value);
+
+/* Allocate new (empty) message */
+struct ha_msg * ha_msg_new(int nfields);
+
+/* Free message */
+void ha_msg_del(struct ha_msg *msg);
+
+/* Copy message */
+struct ha_msg* ha_msg_copy(const struct ha_msg *msg);
+
+int ha_msg_expand(struct ha_msg* msg );
+
+/*Add a null-terminated name and binary value to a message*/
+int ha_msg_addbin(struct ha_msg * msg, const char * name,
+ const void * value, size_t vallen);
+
+int ha_msg_adduuid(struct ha_msg * msg, const char * name,
+ const cl_uuid_t* uuid);
+
+/* Add null-terminated name and a value to the message */
+int ha_msg_add(struct ha_msg * msg
+ , const char* name, const char* value);
+
+int cl_msg_remove(struct ha_msg* msg, const char* name);
+int cl_msg_remove_value(struct ha_msg* msg, const void* value);
+int cl_msg_remove_offset(struct ha_msg* msg, int offset);
+
+/* Modify null-terminated name and a value to the message */
+int cl_msg_modstring(struct ha_msg * msg,
+ const char* name,
+ const char* value);
+int cl_msg_modbin(struct ha_msg * msg,
+ const char* name,
+ const void* value,
+ size_t vlen);
+
+int cl_msg_moduuid(struct ha_msg * msg, const char * name,
+ const cl_uuid_t* uuid);
+
+int cl_msg_modstruct(struct ha_msg * msg,
+ const char* name,
+ const struct ha_msg* value);
+#define ha_msg_mod(msg, name, value) cl_msg_modstring(msg, name, value)
+int cl_msg_replace(struct ha_msg* msg, int index,
+ const void* value, size_t vlen, int type);
+int cl_msg_replace_value(struct ha_msg* msg, const void *old_value,
+ const void* value, size_t vlen, int type);
+
+/* Add name, value (with known lengths) to the message */
+int ha_msg_nadd(struct ha_msg * msg, const char * name, int namelen
+ , const char * value, int vallen);
+
+/* Add a name/value/type to a message (with sizes for name and value) */
+int ha_msg_nadd_type(struct ha_msg * msg, const char * name, int namelen
+ , const char * value, int vallen, int type);
+
+/* Add name=value string to a message */
+int ha_msg_add_nv(struct ha_msg* msg, const char * nvline, const char * bufmax);
+
+
+/* Return value associated with particular name */
+#define ha_msg_value(m,name) cl_get_string(m, name)
+
+/* Call wait(in|out) but only for a finite time */
+int cl_ipc_wait_timeout(
+ IPC_Channel * chan, int (*waitfun)(IPC_Channel * chan), unsigned int timeout);
+
+/* Reads an IPC stream -- converts it into a message */
+struct ha_msg * msgfromIPC_timeout(IPC_Channel *ch, int flag, unsigned int timeout, int *rc_out);
+struct ha_msg * msgfromIPC(IPC_Channel * f, int flag);
+
+IPC_Message * ipcmsgfromIPC(IPC_Channel * ch);
+
+/* Reads a stream -- converts it into a message */
+struct ha_msg * msgfromstream(FILE * f);
+
+/* Reads a stream with string format--converts it into a message */
+struct ha_msg * msgfromstream_string(FILE * f);
+
+/* Reads a stream with netstring format--converts it into a message */
+struct ha_msg * msgfromstream_netstring(FILE * f);
+
+/* Same as above plus copying the iface name to "iface" */
+struct ha_msg * if_msgfromstream(FILE * f, char *iface);
+
+/* Writes a message into a stream */
+int msg2stream(struct ha_msg* m, FILE * f);
+
+/* Converts a message into a string and adds the iface name on start */
+char * msg2if_string(const struct ha_msg *m, const char * iface);
+
+/* Converts a string gotten via UDP into a message */
+struct ha_msg * string2msg(const char * s, size_t length);
+
+/* Converts a message into a string */
+char * msg2string(const struct ha_msg *m);
+
+/* Converts a message into a string in the provided buffer with certain
+depth and with or without start/end */
+int msg2string_buf(const struct ha_msg *m, char* buf,
+ size_t len, int depth, int needhead);
+
+/* Converts a message into wire format */
+char* msg2wirefmt(struct ha_msg *m, size_t* );
+char* msg2wirefmt_noac(struct ha_msg*m, size_t* len);
+
+/* Converts wire format data into a message */
+struct ha_msg* wirefmt2msg(const char* s, size_t length, int flag);
+
+/* Convets wire format data into an IPC message */
+IPC_Message* wirefmt2ipcmsg(void* p, size_t len, IPC_Channel* ch);
+
+/* Converts an ha_msg into an IPC message */
+IPC_Message* hamsg2ipcmsg(struct ha_msg* m, IPC_Channel* ch);
+
+/* Converts an IPC message into an ha_msg */
+struct ha_msg* ipcmsg2hamsg(IPC_Message*m);
+
+/* Outputs a message to an IPC channel */
+int msg2ipcchan(struct ha_msg*m, IPC_Channel*ch);
+
+/* Outpus a message to an IPC channel without authencating
+the message */
+struct ha_msg* msgfromIPC_noauth(IPC_Channel * ch);
+
+/* Reads from control fifo, and creates a new message from it */
+/* This adds the default sequence#, load avg, etc. to the message */
+struct ha_msg * controlfifo2msg(FILE * f);
+
+/* Check if the message is authenticated */
+gboolean isauthentic(const struct ha_msg * msg);
+
+/* Get the required string length for the given message */
+int get_stringlen(const struct ha_msg *m);
+
+/* Get the requried netstring length for the given message*/
+int get_netstringlen(const struct ha_msg *m);
+
+/* Add a child message to a message as a field */
+int ha_msg_addstruct(struct ha_msg * msg, const char * name, const void* ptr);
+
+int ha_msg_addstruct_compress(struct ha_msg*, const char*, const void*);
+
+/* Get binary data from a message */
+const void * cl_get_binary(const struct ha_msg *msg, const char * name, size_t * vallen);
+
+/* Get uuid data from a message */
+int cl_get_uuid(const struct ha_msg *msg, const char * name, cl_uuid_t* retval);
+
+/* Get string data from a message */
+const char * cl_get_string(const struct ha_msg *msg, const char *name);
+
+/* Get the type for a field from a message */
+int cl_get_type(const struct ha_msg *msg, const char *name);
+
+/* Get a child message from a message*/
+struct ha_msg *cl_get_struct(struct ha_msg *msg, const char* name);
+
+/* Log the contents of a message */
+void cl_log_message (int log_level, const struct ha_msg *m);
+
+/* Supply messaging system with old style authentication/authorization method */
+void cl_set_oldmsgauthfunc(gboolean (*authfunc)(const struct ha_msg*));
+
+/* Set default messaging format */
+void cl_set_msg_format(enum cl_msgfmt mfmt);
+
+/* Add a string to a list*/
+int cl_msg_list_add_string(struct ha_msg* msg, const char* name, const char* value);
+
+/* Return length of a list*/
+int cl_msg_list_length(struct ha_msg* msg, const char* name);
+
+/* Return nth element of a list*/
+void* cl_msg_list_nth_data(struct ha_msg* msg, const char* name, int n);
+
+/* Functions to add/mod/get an integer */
+int ha_msg_add_int(struct ha_msg * msg, const char * name, int value);
+int ha_msg_mod_int(struct ha_msg * msg, const char * name, int value);
+int ha_msg_value_int(const struct ha_msg * msg, const char * name, int* value);
+
+/* Functions to add/mod/get an unsigned long */
+int ha_msg_add_ul(struct ha_msg * msg, const char * name, unsigned long value);
+int ha_msg_mod_ul(struct ha_msg * msg, const char * name, unsigned long value);
+int ha_msg_value_ul(const struct ha_msg * msg, const char * name, unsigned long* value);
+
+/* Functions to add/get a string list*/
+GList* ha_msg_value_str_list(struct ha_msg * msg, const char * name);
+
+int cl_msg_add_list_int(struct ha_msg* msg, const char* name,
+ int* buf, size_t n);
+int cl_msg_get_list_int(struct ha_msg* msg, const char* name,
+ int* buf, size_t* n);
+GList* cl_msg_get_list(struct ha_msg* msg, const char* name);
+int cl_msg_add_list(struct ha_msg* msg, const char* name, GList* list);
+int cl_msg_add_list_str(struct ha_msg* msg, const char* name,
+ char** buf, size_t n);
+
+/* Function to add/get a string hash table*/
+GHashTable* ha_msg_value_str_table(struct ha_msg * msg, const char * name);
+int ha_msg_add_str_table(struct ha_msg * msg, const char * name,
+ GHashTable* hash_table);
+int ha_msg_mod_str_table(struct ha_msg * msg, const char * name,
+ GHashTable* hash_table);
+
+/*internal use for list type*/
+size_t string_list_pack_length(const GList* list);
+int string_list_pack(GList* list, char* buf, char* maxp);
+GList* string_list_unpack(const char* packed_str_list, size_t length);
+void list_cleanup(GList* list);
+
+gboolean must_use_netstring(const struct ha_msg*);
+
+
+#endif /* __HA_MSG_H */