File: peers-t.h

package info (click to toggle)
haproxy 3.2.15-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 23,976 kB
  • sloc: ansic: 268,762; sh: 3,489; xml: 1,756; python: 1,345; makefile: 1,159; perl: 168; cpp: 21
file content (254 lines) | stat: -rw-r--r-- 11,513 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * include/haproxy/peers-t.h
 * This file defines everything related to peers.
 *
 * Copyright 2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
 *
 * 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, version 2.1
 * exclusively.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _HAPROXY_PEERS_T_H
#define _HAPROXY_PEERS_T_H

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <import/ebtree-t.h>

#include <haproxy/api-t.h>
#include <haproxy/dict-t.h>
#include <haproxy/stick_table-t.h>
#include <haproxy/thread-t.h>

/* peer state with respects of its applet, as seen from outside */
enum peer_app_state {
	PEER_APP_ST_STOPPED = 0, /* The peer has no applet */
	PEER_APP_ST_STARTING,    /* The peer has an applet with a validated connection but sync task must ack it first */
	PEER_APP_ST_RUNNING,     /* The starting state was processed by the sync task and the peer can process messages */
	PEER_APP_ST_STOPPING,    /* The peer applet was released but the sync task must ack it before switching the peer in STOPPED state */
};

/* peer learn state */
enum peer_learn_state {
	PEER_LR_ST_NOTASSIGNED = 0,/* The peer is not assigned for a leason */
	PEER_LR_ST_ASSIGNED,       /* The peer is assigned for a leason  */
	PEER_LR_ST_PROCESSING,     /* The peer has started the leason and it is not finished */
	PEER_LR_ST_FINISHED,       /* The peer has finished the leason, this state must be ack by the sync task */
};

/******************************/
/* peers section resync flags */
/******************************/
#define PEERS_F_RESYNC_LOCAL_FINISHED     0x00000001 /* Learn from local peer finished or no more needed */
#define PEERS_F_RESYNC_REMOTE_FINISHED    0x00000002 /* Learn from remote peer finished or no more needed */
#define PEERS_F_RESYNC_ASSIGN             0x00000004 /* A peer was assigned to learn our lesson */
/* unused 0x00000008..0x00080000 */
#define PEERS_F_DBG_RESYNC_LOCALTIMEOUT   0x00100000 /* Timeout waiting for a full resync from a local node was experienced at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_REMOTETIMEOUT  0x00200000 /* Timeout waiting for a full resync from a remote node was experienced at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_LOCALABORT     0x00400000 /* Session aborted learning from a local node was experienced at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_REMOTEABORT    0x00800000 /* Session aborted learning from a remote node was experienced at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_LOCALFINISHED  0x01000000 /* A fully up to date local node teach us at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_REMOTEFINISHED 0x02000000 /* A fully up to remote node teach us at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_LOCALPARTIAL   0x04000000 /* A partially up to date local node teach us at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_REMOTEPARTIAL  0x08000000 /* A partially up to date remote node teach us at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_LOCALASSIGN    0x10000000 /* A local node was assigned for a full resync at lest once (for debugging purpose) */
#define PEERS_F_DBG_RESYNC_REMOTEASSIGN   0x20000000 /* A remote node was assigned for a full resync at lest once (for debugging purpose) */

#define PEERS_RESYNC_FROMLOCAL      0x00000000                     /* No resync finished, must be performed from local first */
#define PEERS_RESYNC_FROMREMOTE     PEERS_F_RESYNC_LOCAL_FINISHED  /* Resync from local peer finished, must be performed from remote peer now */
#define PEERS_RESYNC_STATEMASK      (PEERS_F_RESYNC_LOCAL_FINISHED|PEERS_F_RESYNC_REMOTE_FINISHED)
#define PEERS_RESYNC_FINISHED       (PEERS_F_RESYNC_LOCAL_FINISHED|PEERS_F_RESYNC_REMOTE_FINISHED)

/* This function is used to report flags in debugging tools. Please reflect
 * below any single-bit flag addition above in the same order via the
 * __APPEND_FLAG macro. The new end of the buffer is returned.
 */
static forceinline char *peers_show_flags(char *buf, size_t len, const char *delim, uint flg)
{
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
	/* prologue */
	_(0);
	/* flags */
	_(PEERS_F_RESYNC_LOCAL_FINISHED, _(PEERS_F_RESYNC_REMOTE_FINISHED, _(PEERS_F_RESYNC_ASSIGN,
        _(PEERS_F_DBG_RESYNC_LOCALTIMEOUT, _(PEERS_F_DBG_RESYNC_REMOTETIMEOUT,
        _(PEERS_F_DBG_RESYNC_LOCALABORT, _(PEERS_F_DBG_RESYNC_REMOTEABORT,
	_(PEERS_F_DBG_RESYNC_LOCALFINISHED, _(PEERS_F_DBG_RESYNC_REMOTEFINISHED,
	_(PEERS_F_DBG_RESYNC_LOCALPARTIAL, _(PEERS_F_DBG_RESYNC_REMOTEPARTIAL,
	_(PEERS_F_DBG_RESYNC_LOCALASSIGN, _(PEERS_F_DBG_RESYNC_REMOTEABORT)))))))))))));
	/* epilogue */
	_(~0U);
	return buf;
#undef _
}

/******************************/
/* Peer flags                 */
/******************************/
#define PEER_F_TEACH_PROCESS        0x00000001 /* Teach a lesson to current peer */
#define PEER_F_TEACH_FINISHED       0x00000002 /* Teach conclude, (wait for confirm) */
#define PEER_F_LOCAL_TEACH_COMPLETE 0x00000004 /* The old local peer taught all that it known to new one */
#define PEER_F_LEARN_NOTUP2DATE     0x00000008 /* Learn from peer finished but peer is not up to date */
#define PEER_F_WAIT_SYNCTASK_ACK    0x00000010 /* Stop all processing waiting for the sync task acknowledgement when the applet state changes */
#define PEER_F_ALIVE                0x00000020 /* Used to flag a peer a alive. */
#define PEER_F_HEARTBEAT            0x00000040 /* Heartbeat message to send. */
#define PEER_F_DWNGRD               0x00000080 /* When this flag is enabled, we must downgrade the supported version announced during peer sessions. */
/* unused 0x00000100..0x00080000 */
#define PEER_F_DBG_RESYNC_REQUESTED 0x00100000 /* A resnyc was explicitly requested at least once (for debugging purpose) */

#define PEER_TEACH_FLAGS            (PEER_F_TEACH_PROCESS|PEER_F_TEACH_FINISHED)

/* This function is used to report flags in debugging tools. Please reflect
 * below any single-bit flag addition above in the same order via the
 * __APPEND_FLAG macro. The new end of the buffer is returned.
 */
static forceinline char *peer_show_flags(char *buf, size_t len, const char *delim, uint flg)
{
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
	/* prologue */
	_(0);
	/* flags */
	_(PEER_F_TEACH_PROCESS, _(PEER_F_TEACH_FINISHED, _(PEER_F_LOCAL_TEACH_COMPLETE,
        _(PEER_F_LEARN_NOTUP2DATE, _(PEER_F_WAIT_SYNCTASK_ACK,
        _(PEER_F_ALIVE, _(PEER_F_HEARTBEAT, _(PEER_F_DWNGRD,
	_(PEER_F_DBG_RESYNC_REQUESTED)))))))));
	/* epilogue */
	_(~0U);
	return buf;
#undef _
}

struct shared_table {
	struct stktable *table;       /* stick table to sync */
	int local_id;
	int remote_id;
	int flags;
	uint64_t remote_data;
	unsigned int remote_data_nbelem[STKTABLE_DATA_TYPES];
	unsigned int last_acked;
	unsigned int last_pushed;
	unsigned int last_get;
	unsigned int teaching_origin;
	unsigned int update;
	struct shared_table *next;    /* next shared table in list */
};

struct peer {
	int local;                    /* proxy state */
	enum peer_app_state appstate;    /* peer app state */
	enum peer_learn_state learnstate; /* peer learn state */
	__decl_thread(HA_SPINLOCK_T lock); /* lock used to handle this peer section */
	char *id;
	struct {
		const char *file;         /* file where the section appears */
		int line;                 /* line where the section appears */
	} conf;                       /* config information */
	time_t last_change;
	unsigned int flags;           /* peer session flags */
	unsigned int statuscode;      /* current/last session status code */
	unsigned int reconnect;       /* next connect timer */
	unsigned int heartbeat;       /* next heartbeat timer */
	unsigned int confirm;         /* confirm message counter */
	unsigned int last_hdshk;      /* Date of the last handshake. */
	uint32_t rx_hbt;              /* received heartbeats counter */
	uint32_t tx_hbt;              /* transmitted heartbeats counter */
	uint32_t no_hbt;              /* no received heartbeat counter */
	uint32_t new_conn;            /* new connection after reconnection timeout expiration counter */
	uint32_t proto_err;           /* protocol errors counter */
	uint32_t coll;                /* connection collisions counter */
	struct appctx *appctx;        /* the appctx running it */
	struct shared_table *remote_table;
	struct shared_table *last_local_table; /* Last table that emit update messages during a teach process */
	struct shared_table *stop_local_table; /* last evaluated table, used as restart point for the next teach process */
	struct shared_table *tables;
	struct server *srv;
	struct dcache *dcache;        /* dictionary cache */
	struct peers *peers;          /* associated peer section */
	struct peer *next;            /* next peer in the list */
};


struct peers {
	char *id;                       /* peer section name */
	struct task *sync_task;         /* main sync task */
	struct sig_handler *sighandler; /* signal handler */
	struct peer *remote;            /* remote peers list */
	struct peer *local;             /* local peer list */
	struct proxy *peers_fe;         /* peer frontend */
	struct {
		const char *file;           /* file where the section appears */
		int line;                   /* line where the section appears */
	} conf;                         /* config information */
	time_t last_change;
	struct peers *next;             /* next peer section */
	unsigned int flags;             /* current peers section resync state */
	unsigned int resync_timeout;    /* resync timeout timer */
	int count;                      /* total of peers */
	int nb_shards;                  /* Number of peer shards */
	int disabled;                   /* peers proxy disabled if >0 */
	int applet_count[MAX_THREADS];  /* applet count per thread */
};

/* LRU cache for dictionaies */
struct dcache_tx {
	/* The last recently used key */
	unsigned int lru_key;
	/* An array of entries to store pointers to dictionary entries. */
	struct ebpt_node *entries;
	/* The previous lookup result. */
	struct ebpt_node *prev_lookup;
	/* ebtree to store the previous entries. */
	struct eb_root cached_entries;
};

struct dcache_rx {
	unsigned int id;
	struct dict_entry *de;
};

struct dcache_tx_entry {
	unsigned int id;
	struct ebpt_node entry;
};

/* stick-table data type cache */
struct dcache {
	/* Cache used upon transmission */
	struct dcache_tx *tx;
	/* Cache used upon receipt */
	struct dcache_rx *rx;
	/* Maximum number of entries in this cache */
	size_t max_entries;
};

struct peers_keyword {
	const char *kw;
	int (*parse)(
		char **args,
		struct peers *curpeer,
		const char *file,
		int line,
		char **err);
	int flags;
};

struct peers_kw_list {
	struct list list;
	struct peers_keyword kw[VAR_ARRAY];
};

#endif /* _HAPROXY_PEERS_T_H */