Coverage Report

Created: 2026-08-19 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/haproxy/include/haproxy/peers-t.h
Line
Count
Source
1
/*
2
 * include/haproxy/peers-t.h
3
 * This file defines everything related to peers.
4
 *
5
 * Copyright 2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation, version 2.1
10
 * exclusively.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
 */
21
22
#ifndef _HAPROXY_PEERS_T_H
23
#define _HAPROXY_PEERS_T_H
24
25
#include <sys/types.h>
26
#include <sys/socket.h>
27
#include <netinet/in.h>
28
#include <arpa/inet.h>
29
30
#include <import/ebtree-t.h>
31
32
#include <haproxy/api-t.h>
33
#include <haproxy/dict-t.h>
34
#include <haproxy/stick_table-t.h>
35
#include <haproxy/thread-t.h>
36
37
/* peer state with respects of its applet, as seen from outside */
38
enum peer_app_state {
39
  PEER_APP_ST_STOPPED = 0, /* The peer has no applet */
40
  PEER_APP_ST_STARTING,    /* The peer has an applet with a validated connection but sync task must ack it first */
41
  PEER_APP_ST_RUNNING,     /* The starting state was processed by the sync task and the peer can process messages */
42
  PEER_APP_ST_STOPPING,    /* The peer applet was released but the sync task must ack it before switching the peer in STOPPED state */
43
};
44
45
/* peer learn state */
46
enum peer_learn_state {
47
  PEER_LR_ST_NOTASSIGNED = 0,/* The peer is not assigned for a lesson */
48
  PEER_LR_ST_ASSIGNED,       /* The peer is assigned for a lesson  */
49
  PEER_LR_ST_PROCESSING,     /* The peer has started the lesson and it is not finished */
50
  PEER_LR_ST_FINISHED,       /* The peer has finished the lesson, this state must be ack by the sync task */
51
};
52
53
/******************************/
54
/* peers section resync flags */
55
/******************************/
56
0
#define PEERS_F_RESYNC_LOCAL_FINISHED     0x00000001 /* Learn from local peer finished or no more needed */
57
0
#define PEERS_F_RESYNC_REMOTE_FINISHED    0x00000002 /* Learn from remote peer finished or no more needed */
58
0
#define PEERS_F_RESYNC_ASSIGN             0x00000004 /* A peer was assigned to learn our lesson */
59
/* unused 0x00000008..0x00080000 */
60
#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) */
61
#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) */
62
#define PEERS_F_DBG_RESYNC_LOCALABORT     0x00400000 /* Session aborted learning from a local node was experienced at lest once (for debugging purpose) */
63
#define PEERS_F_DBG_RESYNC_REMOTEABORT    0x00800000 /* Session aborted learning from a remote node was experienced at lest once (for debugging purpose) */
64
0
#define PEERS_F_DBG_RESYNC_LOCALFINISHED  0x01000000 /* A fully up to date local node teach us at lest once (for debugging purpose) */
65
0
#define PEERS_F_DBG_RESYNC_REMOTEFINISHED 0x02000000 /* A fully up to remote node teach us at lest once (for debugging purpose) */
66
0
#define PEERS_F_DBG_RESYNC_LOCALPARTIAL   0x04000000 /* A partially up to date local node teach us at lest once (for debugging purpose) */
67
0
#define PEERS_F_DBG_RESYNC_REMOTEPARTIAL  0x08000000 /* A partially up to date remote node teach us at lest once (for debugging purpose) */
68
#define PEERS_F_DBG_RESYNC_LOCALASSIGN    0x10000000 /* A local node was assigned for a full resync at lest once (for debugging purpose) */
69
#define PEERS_F_DBG_RESYNC_REMOTEASSIGN   0x20000000 /* A remote node was assigned for a full resync at lest once (for debugging purpose) */
70
71
0
#define PEERS_RESYNC_FROMLOCAL      0x00000000                     /* No resync finished, must be performed from local first */
72
0
#define PEERS_RESYNC_FROMREMOTE     PEERS_F_RESYNC_LOCAL_FINISHED  /* Resync from local peer finished, must be performed from remote peer now */
73
0
#define PEERS_RESYNC_STATEMASK      (PEERS_F_RESYNC_LOCAL_FINISHED|PEERS_F_RESYNC_REMOTE_FINISHED)
74
0
#define PEERS_RESYNC_FINISHED       (PEERS_F_RESYNC_LOCAL_FINISHED|PEERS_F_RESYNC_REMOTE_FINISHED)
75
76
/* This function is used to report flags in debugging tools. Please reflect
77
 * below any single-bit flag addition above in the same order via the
78
 * __APPEND_FLAG macro. The new end of the buffer is returned.
79
 */
80
static forceinline char *peers_show_flags(char *buf, size_t len, const char *delim, uint flg)
81
0
{
82
0
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
83
0
  /* prologue */
84
0
  _(0);
85
0
  /* flags */
86
0
  _(PEERS_F_RESYNC_LOCAL_FINISHED, _(PEERS_F_RESYNC_REMOTE_FINISHED, _(PEERS_F_RESYNC_ASSIGN,
87
0
        _(PEERS_F_DBG_RESYNC_LOCALTIMEOUT, _(PEERS_F_DBG_RESYNC_REMOTETIMEOUT,
88
0
        _(PEERS_F_DBG_RESYNC_LOCALABORT, _(PEERS_F_DBG_RESYNC_REMOTEABORT,
89
0
  _(PEERS_F_DBG_RESYNC_LOCALFINISHED, _(PEERS_F_DBG_RESYNC_REMOTEFINISHED,
90
0
  _(PEERS_F_DBG_RESYNC_LOCALPARTIAL, _(PEERS_F_DBG_RESYNC_REMOTEPARTIAL,
91
0
  _(PEERS_F_DBG_RESYNC_LOCALASSIGN, _(PEERS_F_DBG_RESYNC_REMOTEASSIGN)))))))))))));
92
0
  /* epilogue */
93
0
  _(~0U);
94
0
  return buf;
95
0
#undef _
96
0
}
Unexecuted instantiation: haproxy.c:peers_show_flags
Unexecuted instantiation: mworker.c:peers_show_flags
Unexecuted instantiation: peers.c:peers_show_flags
Unexecuted instantiation: proxy.c:peers_show_flags
Unexecuted instantiation: stick_table.c:peers_show_flags
Unexecuted instantiation: cfgparse-listen.c:peers_show_flags
Unexecuted instantiation: cfgparse.c:peers_show_flags
Unexecuted instantiation: cli.c:peers_show_flags
Unexecuted instantiation: cfgparse-global.c:peers_show_flags
97
98
/******************************/
99
/* Peer flags                 */
100
/******************************/
101
0
#define PEER_F_TEACH_PROCESS        0x00000001 /* Teach a lesson to current peer */
102
0
#define PEER_F_TEACH_FINISHED       0x00000002 /* Teach conclude, (wait for confirm) */
103
0
#define PEER_F_LOCAL_TEACH_COMPLETE 0x00000004 /* The old local peer taught all that it known to new one */
104
0
#define PEER_F_LEARN_NOTUP2DATE     0x00000008 /* Learn from peer finished but peer is not up to date */
105
0
#define PEER_F_WAIT_SYNCTASK_ACK    0x00000010 /* Stop all processing waiting for the sync task acknowledgement when the applet state changes */
106
0
#define PEER_F_ALIVE                0x00000020 /* Used to flag a peer a alive. */
107
0
#define PEER_F_HEARTBEAT            0x00000040 /* Heartbeat message to send. */
108
0
#define PEER_F_DWNGRD               0x00000080 /* When this flag is enabled, we must downgrade the supported version announced during peer sessions. */
109
/* unused 0x00000100..0x00080000 */
110
0
#define PEER_F_DBG_RESYNC_REQUESTED 0x00100000 /* A resnyc was explicitly requested at least once (for debugging purpose) */
111
112
0
#define PEER_TEACH_FLAGS            (PEER_F_TEACH_PROCESS|PEER_F_TEACH_FINISHED)
113
114
/* This function is used to report flags in debugging tools. Please reflect
115
 * below any single-bit flag addition above in the same order via the
116
 * __APPEND_FLAG macro. The new end of the buffer is returned.
117
 */
118
static forceinline char *peer_show_flags(char *buf, size_t len, const char *delim, uint flg)
119
0
{
120
0
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
121
0
  /* prologue */
122
0
  _(0);
123
0
  /* flags */
124
0
  _(PEER_F_TEACH_PROCESS, _(PEER_F_TEACH_FINISHED, _(PEER_F_LOCAL_TEACH_COMPLETE,
125
0
        _(PEER_F_LEARN_NOTUP2DATE, _(PEER_F_WAIT_SYNCTASK_ACK,
126
0
        _(PEER_F_ALIVE, _(PEER_F_HEARTBEAT, _(PEER_F_DWNGRD,
127
0
  _(PEER_F_DBG_RESYNC_REQUESTED)))))))));
128
0
  /* epilogue */
129
0
  _(~0U);
130
0
  return buf;
131
0
#undef _
132
0
}
Unexecuted instantiation: haproxy.c:peer_show_flags
Unexecuted instantiation: mworker.c:peer_show_flags
Unexecuted instantiation: peers.c:peer_show_flags
Unexecuted instantiation: proxy.c:peer_show_flags
Unexecuted instantiation: stick_table.c:peer_show_flags
Unexecuted instantiation: cfgparse-listen.c:peer_show_flags
Unexecuted instantiation: cfgparse.c:peer_show_flags
Unexecuted instantiation: cli.c:peer_show_flags
Unexecuted instantiation: cfgparse-global.c:peer_show_flags
133
134
struct shared_table {
135
  struct stktable *table;       /* stick table to sync */
136
  int local_id;
137
  int remote_id;
138
  int flags;
139
  uint64_t remote_data;
140
  unsigned int remote_data_nbelem[STKTABLE_DATA_TYPES];
141
  unsigned int last_acked;
142
  unsigned int last_pushed;
143
  unsigned int last_get;
144
  unsigned int teaching_origin;
145
  unsigned int update;
146
  struct shared_table *next;    /* next shared table in list */
147
};
148
149
struct peer {
150
  int local;                    /* proxy state */
151
  enum peer_app_state appstate;    /* peer app state */
152
  enum peer_learn_state learnstate; /* peer learn state */
153
  __decl_thread(HA_SPINLOCK_T lock); /* lock used to handle this peer section */
154
  char *id;
155
  struct {
156
    const char *file;         /* file where the section appears */
157
    int line;                 /* line where the section appears */
158
  } conf;                       /* config information */
159
  time_t last_change;
160
  unsigned int flags;           /* peer session flags */
161
  unsigned int statuscode;      /* current/last session status code */
162
  unsigned int reconnect;       /* next connect timer */
163
  unsigned int heartbeat;       /* next heartbeat timer */
164
  unsigned int confirm;         /* confirm message counter */
165
  unsigned int last_hdshk;      /* Date of the last handshake. */
166
  uint32_t rx_hbt;              /* received heartbeats counter */
167
  uint32_t tx_hbt;              /* transmitted heartbeats counter */
168
  uint32_t no_hbt;              /* no received heartbeat counter */
169
  uint32_t new_conn;            /* new connection after reconnection timeout expiration counter */
170
  uint32_t proto_err;           /* protocol errors counter */
171
  uint32_t coll;                /* connection collisions counter */
172
  struct appctx *appctx;        /* the appctx running it */
173
  struct shared_table *remote_table;
174
  struct shared_table *last_local_table; /* Last table that emit update messages during a teach process */
175
  struct shared_table *stop_local_table; /* last evaluated table, used as restart point for the next teach process */
176
  struct shared_table *tables;
177
  struct server *srv;
178
  struct dcache *dcache;        /* dictionary cache */
179
  struct peers *peers;          /* associated peer section */
180
  struct peer *next;            /* next peer in the list */
181
};
182
183
184
struct peers {
185
  char *id;                       /* peer section name */
186
  struct task *sync_task;         /* main sync task */
187
  struct sig_handler *sighandler; /* signal handler */
188
  struct peer *remote;            /* remote peers list */
189
  struct peer *local;             /* local peer list */
190
  struct proxy *peers_fe;         /* peer frontend */
191
  struct {
192
    const char *file;           /* file where the section appears */
193
    int line;                   /* line where the section appears */
194
  } conf;                         /* config information */
195
  time_t last_change;
196
  struct peers *next;             /* next peer section */
197
  unsigned int flags;             /* current peers section resync state */
198
  unsigned int resync_timeout;    /* resync timeout timer */
199
  int count;                      /* total of peers */
200
  int nb_shards;                  /* Number of peer shards */
201
  int disabled;                   /* peers proxy disabled if >0 */
202
  int applet_count[MAX_THREADS];  /* applet count per thread */
203
};
204
205
/* LRU cache for dictionaies */
206
struct dcache_tx {
207
  /* The last recently used key */
208
  unsigned int lru_key;
209
  /* An array of entries to store pointers to dictionary entries. */
210
  struct ebpt_node *entries;
211
  /* The previous lookup result. */
212
  struct ebpt_node *prev_lookup;
213
  /* ebtree to store the previous entries. */
214
  struct eb_root cached_entries;
215
};
216
217
struct dcache_rx {
218
  unsigned int id;
219
  struct dict_entry *de;
220
};
221
222
struct dcache_tx_entry {
223
  unsigned int id;
224
  struct ebpt_node entry;
225
};
226
227
/* stick-table data type cache */
228
struct dcache {
229
  /* Cache used upon transmission */
230
  struct dcache_tx *tx;
231
  /* Cache used upon receipt */
232
  struct dcache_rx *rx;
233
  /* Maximum number of entries in this cache */
234
  size_t max_entries;
235
};
236
237
struct peers_keyword {
238
  const char *kw;
239
  int (*parse)(
240
    char **args,
241
    struct peers *curpeer,
242
    const char *file,
243
    int line,
244
    char **err);
245
  int flags;
246
};
247
248
struct peers_kw_list {
249
  struct list list;
250
  struct peers_keyword kw[VAR_ARRAY];
251
};
252
253
#endif /* _HAPROXY_PEERS_T_H */
254