Coverage Report

Created: 2023-03-26 06:06

/src/haproxy/include/haproxy/stconn-t.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * include/haproxy/stconn-t.h
3
 * This file describes the stream connector struct and associated constants.
4
 *
5
 * Copyright 2021 Christopher Faulet <cfaulet@haproxy.com>
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_STCONN_T_H
23
#define _HAPROXY_STCONN_T_H
24
25
#include <haproxy/obj_type-t.h>
26
#include <haproxy/connection-t.h>
27
#include <haproxy/show_flags-t.h>
28
29
/* Stream Endpoint Flags.
30
 * Please also update the se_show_flags() function below in case of changes.
31
 */
32
enum se_flags {
33
  SE_FL_NONE       = 0x00000000, /* For initialization purposes */
34
35
   /* Endpoint types */
36
  SE_FL_T_MUX      = 0x00000001, /* The endpoint is a mux (the target may be NULL before the mux init) */
37
  SE_FL_T_APPLET   = 0x00000002, /* The endpoint is an applet */
38
39
   /* unused: 0x00000004 .. 0x00000008 */
40
41
   /* Endpoint states: none == attached to a mux with a stream connector */
42
  SE_FL_DETACHED   = 0x00000010, /* The endpoint is detached (no mux/no applet) */
43
  SE_FL_ORPHAN     = 0x00000020, /* The endpoint is orphan (no stream connector) */
44
45
   /* unused: 0x00000040 .. 0x00000080 */
46
47
  SE_FL_SHRD       = 0x00000100,  /* read shut, draining extra data */
48
  SE_FL_SHRR       = 0x00000200,  /* read shut, resetting extra data */
49
  SE_FL_SHR        = SE_FL_SHRD | SE_FL_SHRR, /* read shut status */
50
51
  SE_FL_SHWN       = 0x00000400,  /* write shut, verbose mode */
52
  SE_FL_SHWS       = 0x00000800,  /* write shut, silent mode */
53
  SE_FL_SHW        = SE_FL_SHWN | SE_FL_SHWS, /* write shut status */
54
55
  /* following flags are supposed to be set by the endpoint and read by
56
   * the app layer :
57
   */
58
59
   /* Permanent flags */
60
  SE_FL_NOT_FIRST  = 0x00001000,  /* This stream connector is not the first one for the endpoint */
61
  SE_FL_WEBSOCKET  = 0x00002000,  /* The endpoint uses the websocket proto */
62
  SE_FL_EOI        = 0x00004000,  /* end-of-input reached */
63
  SE_FL_EOS        = 0x00008000,  /* End of stream delivered to data layer */
64
  SE_FL_ERROR      = 0x00010000,  /* a fatal error was reported */
65
  /* Transient flags */
66
  SE_FL_ERR_PENDING= 0x00020000,  /* An error is pending, but there's still data to be read */
67
  SE_FL_MAY_SPLICE = 0x00040000,  /* The endpoint may use the kernel splicing to forward data to the other side (implies SE_FL_CAN_SPLICE) */
68
  SE_FL_RCV_MORE   = 0x00080000,  /* Endpoint may have more bytes to transfer */
69
  SE_FL_WANT_ROOM  = 0x00100000,  /* More bytes to transfer, but not enough room */
70
  SE_FL_EXP_NO_DATA= 0x00200000,  /* No data expected by the endpoint */
71
  SE_FL_ENDP_MASK  = 0x002ff000,  /* Mask for flags set by the endpoint */
72
73
  /* following flags are supposed to be set by the app layer and read by
74
   * the endpoint :
75
   */
76
  SE_FL_WAIT_FOR_HS   = 0x00400000,  /* This stream is waiting for handhskae */
77
  SE_FL_KILL_CONN     = 0x00800000,  /* must kill the connection when the SC closes */
78
  SE_FL_WAIT_DATA     = 0x01000000,  /* stream endpoint cannot work without more data from the stream's output */
79
  SE_FL_WONT_CONSUME  = 0x02000000,  /* stream endpoint will not consume more data */
80
  SE_FL_HAVE_NO_DATA  = 0x04000000,  /* the endpoint has no more data to deliver to the stream */
81
  /* unused             0x08000000,*/
82
  /* unused             0x10000000,*/
83
  /* unused             0x20000000,*/
84
  SE_FL_APPLET_NEED_CONN = 0x40000000,  /* applet is waiting for the other side to (fail to) connect */
85
};
86
87
/* This function is used to report flags in debugging tools. Please reflect
88
 * below any single-bit flag addition above in the same order via the
89
 * __APPEND_FLAG macro. The new end of the buffer is returned.
90
 */
91
static forceinline char *se_show_flags(char *buf, size_t len, const char *delim, uint flg)
92
0
{
93
0
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
94
0
  /* prologue */
95
0
  _(0);
96
0
  /* flags */
97
0
  _(SE_FL_T_MUX, _(SE_FL_T_APPLET, _(SE_FL_DETACHED, _(SE_FL_ORPHAN,
98
0
  _(SE_FL_SHRD, _(SE_FL_SHRR, _(SE_FL_SHWN, _(SE_FL_SHWS,
99
0
  _(SE_FL_NOT_FIRST, _(SE_FL_WEBSOCKET, _(SE_FL_EOI, _(SE_FL_EOS,
100
0
  _(SE_FL_ERROR, _(SE_FL_ERR_PENDING, _(SE_FL_MAY_SPLICE,
101
0
  _(SE_FL_RCV_MORE, _(SE_FL_WANT_ROOM, _(SE_FL_EXP_NO_DATA,
102
0
  _(SE_FL_WAIT_FOR_HS, _(SE_FL_KILL_CONN, _(SE_FL_WAIT_DATA,
103
0
  _(SE_FL_WONT_CONSUME, _(SE_FL_HAVE_NO_DATA, _(SE_FL_APPLET_NEED_CONN))))))))))))))))))))))));
104
0
  /* epilogue */
105
0
  _(~0U);
106
0
  return buf;
107
0
#undef _
108
0
}
Unexecuted instantiation: cfgparse.c:se_show_flags
Unexecuted instantiation: cli.c:se_show_flags
Unexecuted instantiation: connection.c:se_show_flags
Unexecuted instantiation: debug.c:se_show_flags
Unexecuted instantiation: errors.c:se_show_flags
Unexecuted instantiation: fd.c:se_show_flags
Unexecuted instantiation: filters.c:se_show_flags
Unexecuted instantiation: flt_http_comp.c:se_show_flags
Unexecuted instantiation: frontend.c:se_show_flags
Unexecuted instantiation: haproxy.c:se_show_flags
Unexecuted instantiation: http_ana.c:se_show_flags
Unexecuted instantiation: http_ext.c:se_show_flags
Unexecuted instantiation: http_htx.c:se_show_flags
Unexecuted instantiation: http_rules.c:se_show_flags
Unexecuted instantiation: lb_chash.c:se_show_flags
Unexecuted instantiation: lb_fas.c:se_show_flags
Unexecuted instantiation: lb_fwlc.c:se_show_flags
Unexecuted instantiation: lb_fwrr.c:se_show_flags
Unexecuted instantiation: lb_map.c:se_show_flags
Unexecuted instantiation: listener.c:se_show_flags
Unexecuted instantiation: log.c:se_show_flags
Unexecuted instantiation: mworker.c:se_show_flags
Unexecuted instantiation: peers.c:se_show_flags
Unexecuted instantiation: pool.c:se_show_flags
Unexecuted instantiation: proto_sockpair.c:se_show_flags
Unexecuted instantiation: proxy.c:se_show_flags
Unexecuted instantiation: queue.c:se_show_flags
Unexecuted instantiation: resolvers.c:se_show_flags
Unexecuted instantiation: ring.c:se_show_flags
Unexecuted instantiation: sample.c:se_show_flags
Unexecuted instantiation: server.c:se_show_flags
Unexecuted instantiation: session.c:se_show_flags
Unexecuted instantiation: sink.c:se_show_flags
Unexecuted instantiation: sock.c:se_show_flags
Unexecuted instantiation: stats.c:se_show_flags
Unexecuted instantiation: stconn.c:se_show_flags
Unexecuted instantiation: stick_table.c:se_show_flags
Unexecuted instantiation: stream.c:se_show_flags
Unexecuted instantiation: tcp_rules.c:se_show_flags
Unexecuted instantiation: tcpcheck.c:se_show_flags
Unexecuted instantiation: thread.c:se_show_flags
Unexecuted instantiation: tools.c:se_show_flags
Unexecuted instantiation: trace.c:se_show_flags
Unexecuted instantiation: vars.c:se_show_flags
Unexecuted instantiation: action.c:se_show_flags
Unexecuted instantiation: activity.c:se_show_flags
Unexecuted instantiation: applet.c:se_show_flags
Unexecuted instantiation: backend.c:se_show_flags
Unexecuted instantiation: cache.c:se_show_flags
Unexecuted instantiation: cfgparse-global.c:se_show_flags
Unexecuted instantiation: cfgparse-listen.c:se_show_flags
Unexecuted instantiation: channel.c:se_show_flags
Unexecuted instantiation: check.c:se_show_flags
Unexecuted instantiation: compression.c:se_show_flags
Unexecuted instantiation: dns.c:se_show_flags
Unexecuted instantiation: extcheck.c:se_show_flags
Unexecuted instantiation: fcgi-app.c:se_show_flags
Unexecuted instantiation: flt_spoe.c:se_show_flags
Unexecuted instantiation: http_fetch.c:se_show_flags
Unexecuted instantiation: pattern.c:se_show_flags
Unexecuted instantiation: payload.c:se_show_flags
109
110
/* stconn flags.
111
 * Please also update the sc_show_flags() function below in case of changes.
112
 */
113
enum sc_flags {
114
  SC_FL_NONE          = 0x00000000,  /* Just for initialization purposes */
115
  SC_FL_ISBACK        = 0x00000001,  /* Set for SC on back-side */
116
117
  /* not used: 0x00000002 */
118
  /* not used: 0x00000004 */
119
120
  SC_FL_NOLINGER      = 0x00000008,  /* may close without lingering. One-shot. */
121
  SC_FL_NOHALF        = 0x00000010,  /* no half close, close both sides at once */
122
  SC_FL_DONT_WAKE     = 0x00000020,  /* resync in progress, don't wake up */
123
  SC_FL_INDEP_STR     = 0x00000040,  /* independent streams = don't update rex on write */
124
125
  SC_FL_WONT_READ     = 0x00000080,  /* SC doesn't want to read data */
126
  SC_FL_NEED_BUFF     = 0x00000100,  /* SC waits for an rx buffer allocation to complete */
127
  SC_FL_NEED_ROOM     = 0x00000200,  /* SC needs more room in the rx buffer to store incoming data */
128
};
129
130
/* This function is used to report flags in debugging tools. Please reflect
131
 * below any single-bit flag addition above in the same order via the
132
 * __APPEND_FLAG macro. The new end of the buffer is returned.
133
 */
134
static forceinline char *sc_show_flags(char *buf, size_t len, const char *delim, uint flg)
135
0
{
136
0
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
137
0
  /* prologue */
138
0
  _(0);
139
0
  /* flags */
140
0
  _(SC_FL_ISBACK, _(SC_FL_NOLINGER, _(SC_FL_NOHALF,
141
0
  _(SC_FL_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ,
142
0
  _(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM))))))));
143
0
  /* epilogue */
144
0
  _(~0U);
145
0
  return buf;
146
0
#undef _
147
0
}
Unexecuted instantiation: cfgparse.c:sc_show_flags
Unexecuted instantiation: cli.c:sc_show_flags
Unexecuted instantiation: connection.c:sc_show_flags
Unexecuted instantiation: debug.c:sc_show_flags
Unexecuted instantiation: errors.c:sc_show_flags
Unexecuted instantiation: fd.c:sc_show_flags
Unexecuted instantiation: filters.c:sc_show_flags
Unexecuted instantiation: flt_http_comp.c:sc_show_flags
Unexecuted instantiation: frontend.c:sc_show_flags
Unexecuted instantiation: haproxy.c:sc_show_flags
Unexecuted instantiation: http_ana.c:sc_show_flags
Unexecuted instantiation: http_ext.c:sc_show_flags
Unexecuted instantiation: http_htx.c:sc_show_flags
Unexecuted instantiation: http_rules.c:sc_show_flags
Unexecuted instantiation: lb_chash.c:sc_show_flags
Unexecuted instantiation: lb_fas.c:sc_show_flags
Unexecuted instantiation: lb_fwlc.c:sc_show_flags
Unexecuted instantiation: lb_fwrr.c:sc_show_flags
Unexecuted instantiation: lb_map.c:sc_show_flags
Unexecuted instantiation: listener.c:sc_show_flags
Unexecuted instantiation: log.c:sc_show_flags
Unexecuted instantiation: mworker.c:sc_show_flags
Unexecuted instantiation: peers.c:sc_show_flags
Unexecuted instantiation: pool.c:sc_show_flags
Unexecuted instantiation: proto_sockpair.c:sc_show_flags
Unexecuted instantiation: proxy.c:sc_show_flags
Unexecuted instantiation: queue.c:sc_show_flags
Unexecuted instantiation: resolvers.c:sc_show_flags
Unexecuted instantiation: ring.c:sc_show_flags
Unexecuted instantiation: sample.c:sc_show_flags
Unexecuted instantiation: server.c:sc_show_flags
Unexecuted instantiation: session.c:sc_show_flags
Unexecuted instantiation: sink.c:sc_show_flags
Unexecuted instantiation: sock.c:sc_show_flags
Unexecuted instantiation: stats.c:sc_show_flags
Unexecuted instantiation: stconn.c:sc_show_flags
Unexecuted instantiation: stick_table.c:sc_show_flags
Unexecuted instantiation: stream.c:sc_show_flags
Unexecuted instantiation: tcp_rules.c:sc_show_flags
Unexecuted instantiation: tcpcheck.c:sc_show_flags
Unexecuted instantiation: thread.c:sc_show_flags
Unexecuted instantiation: tools.c:sc_show_flags
Unexecuted instantiation: trace.c:sc_show_flags
Unexecuted instantiation: vars.c:sc_show_flags
Unexecuted instantiation: action.c:sc_show_flags
Unexecuted instantiation: activity.c:sc_show_flags
Unexecuted instantiation: applet.c:sc_show_flags
Unexecuted instantiation: backend.c:sc_show_flags
Unexecuted instantiation: cache.c:sc_show_flags
Unexecuted instantiation: cfgparse-global.c:sc_show_flags
Unexecuted instantiation: cfgparse-listen.c:sc_show_flags
Unexecuted instantiation: channel.c:sc_show_flags
Unexecuted instantiation: check.c:sc_show_flags
Unexecuted instantiation: compression.c:sc_show_flags
Unexecuted instantiation: dns.c:sc_show_flags
Unexecuted instantiation: extcheck.c:sc_show_flags
Unexecuted instantiation: fcgi-app.c:sc_show_flags
Unexecuted instantiation: flt_spoe.c:sc_show_flags
Unexecuted instantiation: http_fetch.c:sc_show_flags
Unexecuted instantiation: pattern.c:sc_show_flags
Unexecuted instantiation: payload.c:sc_show_flags
148
149
/* A conn stream must have its own errors independently of the buffer's, so that
150
 * applications can rely on what the buffer reports while the conn stream is
151
 * performing some retries (eg: connection error). Some states are transient and
152
 * do not last beyond process_session().
153
 */
154
enum sc_state {
155
  SC_ST_INI = 0,           /* SC not sollicitated yet */
156
  SC_ST_REQ,               /* [transient] connection initiation desired and not started yet */
157
  SC_ST_QUE,               /* SC waiting in queue */
158
  SC_ST_TAR,               /* SC in turn-around state after failed connect attempt */
159
  SC_ST_ASS,               /* server just assigned to this SC */
160
  SC_ST_CON,               /* initiated connection request (resource exists) */
161
  SC_ST_CER,               /* [transient] previous connection attempt failed (resource released) */
162
  SC_ST_RDY,               /* [transient] ready proven after I/O success during SC_ST_CON */
163
  SC_ST_EST,               /* connection established (resource exists) */
164
  SC_ST_DIS,               /* [transient] disconnected from other side, but cleanup not done yet */
165
  SC_ST_CLO,               /* SC closed, might not existing anymore. Buffers shut. */
166
} __attribute__((packed));
167
168
/* state bits for use with lists of states */
169
enum sc_state_bit {
170
  SC_SB_NONE = 0,
171
  SC_SB_INI = 1U << SC_ST_INI,
172
  SC_SB_REQ = 1U << SC_ST_REQ,
173
  SC_SB_QUE = 1U << SC_ST_QUE,
174
  SC_SB_TAR = 1U << SC_ST_TAR,
175
  SC_SB_ASS = 1U << SC_ST_ASS,
176
  SC_SB_CON = 1U << SC_ST_CON,
177
  SC_SB_CER = 1U << SC_ST_CER,
178
  SC_SB_RDY = 1U << SC_ST_RDY,
179
  SC_SB_EST = 1U << SC_ST_EST,
180
  SC_SB_DIS = 1U << SC_ST_DIS,
181
  SC_SB_CLO = 1U << SC_ST_CLO,
182
  SC_SB_ALL = SC_SB_INI|SC_SB_REQ|SC_SB_QUE|SC_SB_TAR|SC_SB_ASS|SC_SB_CON|SC_SB_CER|SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO,
183
};
184
185
struct stconn;
186
187
/* A Stream Endpoint Descriptor (sedesc) is the link between the stream
188
 * connector (ex. stconn) and the Stream Endpoint (mux or appctx).
189
 * It always exists for either of them, and binds them together. It also
190
 * contains some shared information relative to the endpoint. It is created by
191
 * the first one which needs it and is shared by the other one, i.e. on the
192
 * client side, it's created the mux or applet and shared with the connector.
193
 * An sedesc without stconn is called an ORPHANED descriptor. An sedesc with
194
 * no mux/applet is called a DETACHED descriptor. Upon detach, the connector
195
 * transfers the whole responsibility of the endpoint descriptor to the
196
 * endpoint itself (mux/applet) and eventually creates a new sedesc (for
197
 * instance on connection retries).
198
 *
199
 * <se>     is the stream endpoint, i.e. the mux stream or the appctx
200
 * <conn>   is the connection for connection-based streams
201
 * <sc>     is the stream connector we're attached to, or NULL
202
 * <lra>    is the last read activity
203
 * <fsb>    is the first send blocked
204
 * <flags>  SE_FL_*
205
 *
206
 * <lra> should be updated when a read activity is detected. It can be a
207
 *       sucessful receive, when a shutr is reported or when receives are
208
 *       unblocked.
209
210
 * <fsb> should be updated when the first send of a series is blocked and reset
211
 *       when a successful send is reported.
212
 */
213
struct sedesc {
214
  void *se;
215
  struct connection *conn;
216
  struct stconn *sc;
217
  unsigned int flags;
218
  unsigned int lra;
219
  unsigned int fsb;
220
};
221
222
/* sc_app_ops describes the application layer's operations and notification
223
 * callbacks when I/O activity is reported and to use to perform shutr/shutw.
224
 * There are very few combinations in practice (strm/chk <-> none/mux/applet).
225
 */
226
struct sc_app_ops {
227
  void (*chk_rcv)(struct stconn *);    /* chk_rcv function, may not be null */
228
  void (*chk_snd)(struct stconn *);    /* chk_snd function, may not be null */
229
  void (*shutr)(struct stconn *);      /* shut read function, may not be null */
230
  void (*shutw)(struct stconn *);      /* shut write function, may not be null */
231
  int  (*wake)(struct stconn *);       /* data-layer callback to report activity */
232
  char name[8];                        /* data layer name, zero-terminated */
233
};
234
235
/*
236
 * This structure describes the elements of a connection relevant to a stream
237
 */
238
struct stconn {
239
  enum obj_type obj_type;              /* differentiates connection from applet context */
240
  enum sc_state state;                 /* SC_ST* */
241
  /* 2 bytes hole here */
242
243
  unsigned int flags;                  /* SC_FL_* */
244
  unsigned int ioto;                   /* I/O activity timeout */
245
  struct wait_event wait_event;        /* We're in a wait list */
246
  struct sedesc *sedesc;               /* points to the stream endpoint descriptor */
247
  enum obj_type *app;                  /* points to the applicative point (stream or check) */
248
  const struct sc_app_ops *app_ops;    /* general operations used at the app layer */
249
  struct sockaddr_storage *src;        /* source address (pool), when known, otherwise NULL */
250
  struct sockaddr_storage *dst;        /* destination address (pool), when known, otherwise NULL */
251
};
252
253
254
#endif /* _HAPROXY_STCONN_T_H */