/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 */ |