mirror of https://github.com/sipwise/heartbeat.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
460 lines
17 KiB
460 lines
17 KiB
/*
|
|
* 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)
|
|
|
|
/* Reads an IPC stream -- converts it into a message */
|
|
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 */
|