1 #ifndef INCLUDE_node_h__
2 #define INCLUDE_node_h__
5 #include <netinet/in.h>
7 #include <nagios/lib/iocache.h>
8 #include <nagios/nebcallbacks.h>
13 #if __BYTE_ORDER == __BIG_ENDIAN
14 # define MERLIN_SIGNATURE (uint64_t)0x4d524c4e45565400LL /* "MRLNEVT\0" */
16 # define MERLIN_SIGNATURE (uint64_t)0x005456454e4c524dLL /* "MRLNEVT\0" */
19 #define MERLIN_PROTOCOL_VERSION 1
21 * how long we should wait before sending paths before trying
22 * to send them again in case something weird happens
24 #define MERLIN_SENDPATH_INTERVAL 15
27 * flags for node options. Must be powers of 2
29 #define MERLIN_NODE_TAKEOVER (1 << 0)
30 #define MERLIN_NODE_CONNECT (1 << 1)
31 #define MERLIN_NODE_FIXED_SRCPORT (1 << 2)
32 #define MERLIN_NODE_NOTIFIES (1 << 3)
34 #define MERLIN_NODE_DEFAULT_POLLER_FLAGS \
35 (MERLIN_NODE_TAKEOVER | MERLIN_NODE_CONNECT | MERLIN_NODE_NOTIFIES)
36 #define MERLIN_NODE_DEFAULT_PEER_FLAGS (MERLIN_NODE_CONNECT)
37 #define MERLIN_NODE_DEFAULT_MASTER_FLAGS (MERLIN_NODE_CONNECT)
38 #define MERLIN_NODE_DEFAULT_IPC_FLAGS (MERLIN_NODE_NOTIFIES)
40 /* various magic options for the "type" field */
41 #define CTRL_PACKET 0xffff /* control packet. "code" described below */
42 #define ACK_PACKET 0xfffe /* ACK ("I understood") (not used) */
43 #define NAK_PACKET 0xfffd /* NAK ("I don't understand") (not used) */
45 /* If "type" is CTRL_PACKET, then "code" is one of the following */
46 #define CTRL_GENERIC 0 /* generic control packet */
47 #define CTRL_PULSE 1 /* keep-alive signal */
48 #define CTRL_INACTIVE 2 /* signals that a slave went offline */
49 #define CTRL_ACTIVE 3 /* signals that a slave went online */
50 #define CTRL_PATHS 4 /* body contains paths to import */
51 #define CTRL_STALL 5 /* signal that we can't accept events for a while */
52 #define CTRL_RESUME 6 /* now we can accept events again */
53 #define CTRL_STOP 7 /* exit() immediately (only accepted via ipc) */
54 /* the following magic entries can be used for the "code" entry */
55 #define MAGIC_NONET 0xffff /* don't forward to the network */
58 * Mark "selection" with this to generate broadcast-ish
59 * events for various classes of merlin-nodes
61 #define DEST_BROADCAST 0xffff /* all nodes */
62 #define DEST_MAGIC (0xfff0)
63 #define DEST_POLLERS (DEST_MAGIC + (1 << 1)) /* all pollers */
64 #define DEST_PEERS (DEST_MAGIC + (1 << 2)) /* all peers */
65 #define DEST_MASTERS (DEST_MAGIC + (1 << 3)) /* all masters */
66 #define DEST_PEERS_POLLERS (DEST_POLLERS | DEST_PEERS)
67 #define DEST_PEERS_MASTERS (DEST_PEERS | DEST_MASTERS)
68 #define DEST_POLLERS_MASTERS (DEST_POLLERS | DEST_MASTERS)
69 #define magic_destination(pkt) ((pkt->hdr.selection & 0xfff0) == 0xfff0)
72 #define HDR_SIZE (sizeof(merlin_header))
73 #define PKT_SIZE (sizeof(merlin_event))
74 #define MAX_PKT_SIZE (PKT_SIZE)
75 #define packet_size(pkt) ((int)((pkt)->hdr.len + HDR_SIZE))
77 struct merlin_header
{
78 union merlin_signature
{
79 uint64_t id
; /* used for assignment and comparison */
80 char ascii
[8]; /* "MRLNEVT\0" for debugging, mostly */
82 uint16_t protocol
; /* protocol version */
83 uint16_t type
; /* event type */
84 uint16_t code
; /* event code (used for control packets) */
85 uint16_t selection
; /* used when noc Nagios communicates with mrd */
86 uint32_t len
; /* size of body */
87 struct timeval sent
; /* when this message was sent */
89 /* pad to 64 bytes for future extensions */
90 char padding
[64 - sizeof(struct timeval
) - (2 * 6) - 8];
91 } __attribute__((packed
));
92 typedef struct merlin_header merlin_header
;
97 } __attribute__((packed
));
98 typedef struct merlin_event merlin_event
;
101 * New entries in this struct *must* be appended LAST for the change
102 * to not break backwards compatibility. When the receiving code
103 * expects a new entry from this struct to exist, it should take care
104 * to mark the size of the received packet and never access anything
106 * Since it gets copied into pre-allocated memory, we needn't bother
107 * about the fields we never set. Newly added fields just shouldn't
108 * ever have an expected value of 0 when it exists, since that's what
109 * they will be if the sending end doesn't have the field we want to
111 * Thus, we must make sure to always use fixed-size entries in this
114 /* change this macro when nodeinfo is rearranged */
115 #define MERLIN_NODEINFO_VERSION 1
116 /* change this macro when the struct grows incompatibly */
117 #define MERLIN_NODEINFO_MINSIZE sizeof(struct merlin_nodeinfo)
118 struct merlin_nodeinfo
{
119 uint32_t version
; /* version of this structure */
120 uint32_t word_size
; /* bits per register (sizeof(void *) * 8) */
121 uint32_t byte_order
; /* 1234 = little, 4321 = big, ... */
122 uint32_t object_structure_version
;
123 struct timeval start
; /* module (or daemon) start time */
124 time_t last_cfg_change
; /* when config was last changed */
125 unsigned char config_hash
[20]; /* SHA1 hash of object config hash */
126 uint32_t peer_id
; /* self-assigned peer-id */
127 uint32_t active_peers
;
128 uint32_t configured_peers
;
129 uint32_t active_pollers
;
130 uint32_t configured_pollers
;
131 uint32_t active_masters
;
132 uint32_t configured_masters
;
133 uint32_t host_checks_handled
;
134 uint32_t service_checks_handled
;
135 uint32_t monitored_object_state_size
;
136 /* new entries have to come LAST */
137 } __attribute__((packed
));
138 typedef struct merlin_nodeinfo merlin_nodeinfo
;
140 struct merlin_child
{
144 typedef struct merlin_child merlin_child
;
146 struct merlin_confsync
{
151 typedef struct merlin_confsync merlin_confsync
;
153 /* 1MB receive buffer should work nicely */
154 #define MERLIN_IOC_BUFSIZE (1 * 1024 * 1024)
156 struct statistics_vars
{
157 unsigned long long sent
, read
, logged
, dropped
;
159 struct callback_count
{
160 unsigned int in
, out
;
162 struct merlin_node_stats
{
163 struct statistics_vars events
, bytes
;
164 time_t last_logged
; /* when we logged the event-count last */
165 struct callback_count cb_count
[NEBCALLBACK_NUMITEMS
+ 1];
167 typedef struct merlin_node_stats merlin_node_stats
;
169 /* used for various objects which we build linked lists for */
170 typedef struct linked_item
{
172 struct linked_item
*next_item
;
175 struct node_selection
{
180 typedef struct node_selection node_selection
;
185 #define MODE_MASTER MODE_NOC /* alias for MODE_NOC */
186 #define MODE_PEER (1 << 1)
187 #define MODE_POLLER (1 << 2)
188 #define MODE_INTERNAL (1 << 3)
190 /* for node->state */
192 #define STATE_PENDING 1
193 #define STATE_NEGOTIATING 2
194 #define STATE_CONNECTED 3
196 #define NODE_WARN_CLOCK 1 /* clock skew warning */
199 char *name
; /* name of this node */
200 char *source_name
; /* check source name for this node */
201 char *hostgroups
; /* only used for pollers */
202 uint id
; /* internal index lookup number */
203 int latency
; /* module to module latency of this node */
204 int sock
; /* the socket */
205 int type
; /* server type (master, slave, peer) */
206 int state
; /* state of this node (down, pending, active) */
207 uint32_t peer_id
; /* peer id, used to distribute checks */
208 int flags
; /* flags for this node */
209 struct sockaddr
*sa
; /* should always point to sain */
210 struct sockaddr_in sain
;
211 unsigned int data_timeout
; /* send gracetime before we disconnect */
212 unsigned int host_checks
; /* actually executed host checks */
213 unsigned int service_checks
; /* actually executed service checks */
214 unsigned int warn_flags
; /* warnings caught from this node */
215 time_t last_recv
; /* last time node sent something to us */
216 time_t last_sent
; /* when we sent something last */
217 time_t last_conn_attempt_logged
; /* when we last logged a connect attempt */
218 time_t last_conn_attempt
; /* when we last tried initiating a connection */
219 time_t connect_time
; /* when we established a connection to this node */
220 merlin_peer_group
*pgroup
; /* this node's peer-group (if a poller) */
222 struct merlin_assigned_objects passive
; /* passive check modifiers */
223 struct merlin_assigned_objects extra
; /* taken over from a poller */
224 struct merlin_assigned_objects current
; /* base assigned right now */
225 struct merlin_assigned_objects expired
; /* expired checks */
227 merlin_nodeinfo info
; /* node info */
228 int last_action
; /* LA_CONNECT | LA_DISCONNECT | LA_HANDLED */
229 binlog
*binlog
; /* binary backlog for this node */
230 merlin_node_stats stats
; /* event/data statistics */
231 iocache
*ioc
; /* I/O cache for bulk reads */
232 merlin_confsync csync
; /* config synchronization configuration */
233 unsigned int csync_num_attempts
;
234 unsigned int csync_max_attempts
;
235 time_t csync_last_attempt
;
236 int (*action
)(struct merlin_node
*, int); /* (daemon) action handler */
238 typedef struct merlin_node merlin_node
;
240 #define node_table noc_table
241 extern merlin_node
**noc_table
, **peer_table
, **poller_table
;
243 extern node_selection
*node_selection_by_name(const char *name
);
244 extern char *get_sel_name(int index
);
245 extern int get_sel_id(const char *name
);
246 extern int get_num_selections(void);
247 extern linked_item
*nodes_by_sel_id(int sel
);
248 extern linked_item
*nodes_by_sel_name(const char *name
);
249 extern void node_grok_config(struct cfg_comp
*config
);
250 extern void node_log_event_count(merlin_node
*node
, int force
);
251 extern void node_disconnect(merlin_node
*node
, const char *fmt
, ...);
252 extern int node_send(merlin_node
*node
, void *data
, unsigned int len
, int flags
);
253 extern int node_send_event(merlin_node
*node
, merlin_event
*pkt
, int msec
);
254 extern int node_recv(merlin_node
*node
);
255 extern merlin_event
*node_get_event(merlin_node
*node
);
256 extern int node_send_binlog(merlin_node
*node
, merlin_event
*pkt
);
257 extern const char *node_state(merlin_node
*node
);
258 extern const char *node_type(merlin_node
*node
);
259 extern void node_set_state(merlin_node
*node
, int state
, const char *reason
);
260 extern int node_ctrl(merlin_node
*node
, int code
, uint selection
, void *data
, uint32_t len
, int msec
);
261 extern merlin_node
*node_by_id(uint id
);
262 int handle_ctrl_active(merlin_node
*node
, merlin_event
*pkt
);
265 * we make these inlined rather than macros so the compiler
266 * does type-checking in the arguments
268 static inline int node_send_ctrl_inactive(merlin_node
*node
, uint id
, int msec
)
270 return node_ctrl(node
, CTRL_INACTIVE
, id
, NULL
, 0, msec
);
273 static inline int node_send_ctrl_active(merlin_node
*node
, uint id
, merlin_nodeinfo
*info
, int msec
)
275 return node_ctrl(node
, CTRL_ACTIVE
, id
, (void *)info
, sizeof(*info
), msec
);