/src/haproxy/include/haproxy/connection-t.h
Line | Count | Source |
1 | | /* |
2 | | * include/haproxy/connection-t.h |
3 | | * This file describes the connection struct and associated constants. |
4 | | * |
5 | | * Copyright (C) 2000-2014 Willy Tarreau - w@1wt.eu |
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_CONNECTION_T_H |
23 | | #define _HAPROXY_CONNECTION_T_H |
24 | | |
25 | | #include <stdlib.h> |
26 | | #include <sys/socket.h> |
27 | | #include <netinet/in_systm.h> |
28 | | #include <netinet/ip.h> |
29 | | #include <netinet/ip6.h> |
30 | | |
31 | | #include <import/cebtree.h> |
32 | | #include <import/ist.h> |
33 | | |
34 | | #include <haproxy/api-t.h> |
35 | | #include <haproxy/buf-t.h> |
36 | | #include <haproxy/obj_type-t.h> |
37 | | #include <haproxy/port_range-t.h> |
38 | | #include <haproxy/protocol-t.h> |
39 | | #include <haproxy/show_flags-t.h> |
40 | | #include <haproxy/task-t.h> |
41 | | #include <haproxy/thread-t.h> |
42 | | |
43 | | /* referenced below */ |
44 | | struct connection; |
45 | | struct stconn; |
46 | | struct sedesc; |
47 | | struct se_abort_info; |
48 | | struct cs_info; |
49 | | struct buffer; |
50 | | struct proxy; |
51 | | struct server; |
52 | | struct session; |
53 | | struct pipe; |
54 | | struct quic_conn; |
55 | | struct bind_conf; |
56 | | struct qcs; |
57 | | struct ssl_sock_ctx; |
58 | | |
59 | | /* For each direction, we have a CO_FL_XPRT_<DIR>_ENA flag, which |
60 | | * indicates if read or write is desired in that direction for the respective |
61 | | * layers. The current status corresponding to the current layer being used is |
62 | | * remembered in the CO_FL_XPRT_<DIR>_ENA flag. The need to poll (ie receipt of |
63 | | * EAGAIN) is remembered at the file descriptor level so that even when the |
64 | | * activity is stopped and restarted, we still remember whether it was needed |
65 | | * to poll before attempting the I/O. |
66 | | * |
67 | | * The FD state is updated according to CO_FL_XPRT_<DIR>_ENA in |
68 | | * conn_cond_update_polling(). |
69 | | */ |
70 | | |
71 | | /* A bit of explanation is required for backend connection reuse. A connection |
72 | | * may be shared between multiple streams of the same thread (e.g. h2, fcgi, |
73 | | * quic) and may be reused by subsequent streams of a different thread if it |
74 | | * is totally idle (i.e. not used at all). In order to permit other streams |
75 | | * to find a connection, it has to appear in lists and/or trees that reflect |
76 | | * its current state. If the connection is full and cannot be shared anymore, |
77 | | * it is not in any of such places. The various states are the following: |
78 | | * |
79 | | * - private: a private connection is not visible to other threads. It is |
80 | | * attached via its <idle_list> member to the <conn_list> head of a |
81 | | * sess_priv_conns struct specific to the server, itself attached to the |
82 | | * session. Only other streams of the same session may find this connection. |
83 | | * Such connections include totally idle connections as well as connections |
84 | | * with available slots left. The <hash_node> part is still used to store |
85 | | * the hash key but the tree node part is otherwise left unused. |
86 | | * |
87 | | * - avail: an available connection is a connection that has at least one |
88 | | * stream in use and at least one slot available for a new stream. Such a |
89 | | * connection is indexed in the server's <avail_conns> member based on the |
90 | | * key of the hash_node. It cannot be used by other threads, and is not |
91 | | * present in the server's <idle_conn_list>, so its <idle_list> member is |
92 | | * always empty. Since this connection is in use by a single thread and |
93 | | * cannot be taken over, it doesn't require any locking to enter/leave the |
94 | | * tree. |
95 | | * |
96 | | * - safe: a safe connection is an idle connection that has proven that it |
97 | | * could reliably be reused. Such a connection may be taken over at any |
98 | | * instant by other threads, and must only be manipulated under the server's |
99 | | * <idle_lock>. It is indexed in the server's <safe_conns> member based on |
100 | | * the key of the hash_node. It is attached to the server's <idle_conn_list> |
101 | | * via its <idle_list> member. It may be purged after too long inactivity, |
102 | | * though the thread responsible for doing this will first take it over. Such |
103 | | * a connection has (conn->flags & CO_FL_LIST_MASK) = CO_FL_SAFE_LIST. |
104 | | * |
105 | | * - idle: a purely idle connection has not yet proven that it could reliably |
106 | | * be reused. Such a connection may be taken over at any instant by other |
107 | | * threads, and must only be manipulated under the server's <idle_lock>. It |
108 | | * is indexed in the server's <idle_conns> member based on the key of the |
109 | | * hash_node. It is attached to the server's <idle_conn_list> via its |
110 | | * <idle_list> member. It may be purged after too long inactivity, though the |
111 | | * thread responsible for doing this will first take it over. Such a |
112 | | * connection has (conn->flags & CO_FL_LIST_MASK) = CO_FL_IDLE_LIST. |
113 | | */ |
114 | | |
115 | | /* flags for use in connection->flags. Please also update the conn_show_flags() |
116 | | * function below in case of changes. |
117 | | */ |
118 | | enum { |
119 | | CO_FL_NONE = 0x00000000, /* Just for initialization purposes */ |
120 | | |
121 | | /* Do not change these values without updating conn_*_poll_changes() ! */ |
122 | | CO_FL_SAFE_LIST = 0x00000001, /* 0 = not in any list, 1 = in safe_list */ |
123 | | CO_FL_IDLE_LIST = 0x00000002, /* 2 = in idle_list, 3 = invalid */ |
124 | | CO_FL_LIST_MASK = 0x00000003, /* Is the connection in any server-managed list ? */ |
125 | | |
126 | | CO_FL_REVERSED = 0x00000004, /* connection has been reversed to backend / reversed and accepted on frontend */ |
127 | | CO_FL_ACT_REVERSING = 0x00000008, /* connection has been reversed to frontend but not yet accepted */ |
128 | | |
129 | | CO_FL_OPT_MARK = 0x00000010, /* connection has a special sockopt mark */ |
130 | | |
131 | | CO_FL_OPT_TOS = 0x00000020, /* connection has a special sockopt tos */ |
132 | | |
133 | | /* unused : 0x00000040, 0x00000080 */ |
134 | | |
135 | | /* These flags indicate whether the Control and Transport layers are initialized */ |
136 | | CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */ |
137 | | CO_FL_XPRT_READY = 0x00000200, /* xprt_start() done, xprt can be used */ |
138 | | |
139 | | CO_FL_WANT_DRAIN = 0x00000400, /* try to drain pending data when closing */ |
140 | | |
141 | | /* This flag is used by data layers to indicate they had to stop |
142 | | * receiving data because a buffer was full. The connection handler |
143 | | * clears it before first calling the I/O and data callbacks. |
144 | | */ |
145 | | CO_FL_WAIT_ROOM = 0x00000800, /* data sink is full */ |
146 | | |
147 | | CO_FL_WANT_SPLICING = 0x00001000, /* we wish to use splicing on the connection when possible */ |
148 | | CO_FL_SSL_NO_CACHED_INFO = 0x00002000, /* Don't use any cached information when creating a new SSL connection */ |
149 | | /* unused: 0x00002000 */ |
150 | | |
151 | | CO_FL_EARLY_SSL_HS = 0x00004000, /* We have early data pending, don't start SSL handshake yet */ |
152 | | CO_FL_EARLY_DATA = 0x00008000, /* At least some of the data are early data */ |
153 | | CO_FL_SOCKS4_SEND = 0x00010000, /* handshaking with upstream SOCKS4 proxy, going to send the handshake */ |
154 | | CO_FL_SOCKS4_RECV = 0x00020000, /* handshaking with upstream SOCKS4 proxy, going to check if handshake succeed */ |
155 | | |
156 | | /* flags used to remember what shutdown have been performed/reported */ |
157 | | CO_FL_SOCK_RD_SH = 0x00040000, /* SOCK layer was notified about shutr/read0 */ |
158 | | CO_FL_SOCK_WR_SH = 0x00080000, /* SOCK layer asked for shutw */ |
159 | | |
160 | | /* flags used to report connection errors or other closing conditions */ |
161 | | CO_FL_ERROR = 0x00100000, /* a fatal error was reported */ |
162 | | CO_FL_NOTIFY_DONE = 0x001C0000, /* any xprt shut/error flags above needs to be reported */ |
163 | | |
164 | | CO_FL_FDLESS = 0x00200000, /* this connection doesn't use any FD (e.g. QUIC) */ |
165 | | |
166 | | /* flags used to report connection status updates */ |
167 | | CO_FL_WAIT_L4_CONN = 0x00400000, /* waiting for L4 to be connected */ |
168 | | CO_FL_WAIT_L6_CONN = 0x00800000, /* waiting for L6 to be connected (eg: SSL) */ |
169 | | CO_FL_WAIT_L4L6 = 0x00C00000, /* waiting for L4 and/or L6 to be connected */ |
170 | | |
171 | | /* All the flags below are used for connection handshakes. Any new |
172 | | * handshake should be added after this point, and CO_FL_HANDSHAKE |
173 | | * should be updated. |
174 | | */ |
175 | | CO_FL_SEND_PROXY = 0x01000000, /* send a valid PROXY protocol header */ |
176 | | CO_FL_ACCEPT_PROXY = 0x02000000, /* receive a valid PROXY protocol header */ |
177 | | CO_FL_ACCEPT_CIP = 0x04000000, /* receive a valid NetScaler Client IP header */ |
178 | | |
179 | | /* below we have all handshake flags grouped into one */ |
180 | | CO_FL_HANDSHAKE = CO_FL_SEND_PROXY | CO_FL_ACCEPT_PROXY | CO_FL_ACCEPT_CIP | CO_FL_SOCKS4_SEND | CO_FL_SOCKS4_RECV, |
181 | | CO_FL_WAIT_XPRT = CO_FL_WAIT_L4_CONN | CO_FL_HANDSHAKE | CO_FL_WAIT_L6_CONN, |
182 | | |
183 | | CO_FL_SSL_WAIT_HS = 0x08000000, /* wait for an SSL handshake to complete */ |
184 | | |
185 | | /* This connection may not be shared between clients */ |
186 | | CO_FL_PRIVATE = 0x10000000, |
187 | | |
188 | | /* This flag is used to know that a PROXY protocol header was sent by the client */ |
189 | | CO_FL_RCVD_PROXY = 0x20000000, |
190 | | |
191 | | /* The connection is unused by its owner */ |
192 | | CO_FL_SESS_IDLE = 0x40000000, |
193 | | |
194 | | /* This last flag indicates that the transport layer is used (for instance |
195 | | * by logs) and must not be cleared yet. The last call to conn_xprt_close() |
196 | | * must be done after clearing this flag. |
197 | | */ |
198 | | CO_FL_XPRT_TRACKED = 0x80000000, |
199 | | |
200 | | /* below we have all SOCKS handshake flags grouped into one */ |
201 | | CO_FL_SOCKS4 = CO_FL_SOCKS4_SEND | CO_FL_SOCKS4_RECV, |
202 | | }; |
203 | | |
204 | | /* This function is used to report flags in debugging tools. Please reflect |
205 | | * below any single-bit flag addition above in the same order via the |
206 | | * __APPEND_FLAG macro. The new end of the buffer is returned. |
207 | | */ |
208 | | static forceinline char *conn_show_flags(char *buf, size_t len, const char *delim, uint flg) |
209 | 0 | { |
210 | 0 | #define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__) |
211 | 0 | /* prologue */ |
212 | 0 | _(0); |
213 | 0 | /* flags */ |
214 | 0 | _(CO_FL_SAFE_LIST, _(CO_FL_IDLE_LIST, _(CO_FL_CTRL_READY, |
215 | 0 | _(CO_FL_REVERSED, _(CO_FL_ACT_REVERSING, _(CO_FL_OPT_MARK, _(CO_FL_OPT_TOS, |
216 | 0 | _(CO_FL_XPRT_READY, _(CO_FL_WANT_DRAIN, _(CO_FL_WAIT_ROOM, _(CO_FL_SSL_NO_CACHED_INFO, _(CO_FL_EARLY_SSL_HS, |
217 | 0 | _(CO_FL_EARLY_DATA, _(CO_FL_SOCKS4_SEND, _(CO_FL_SOCKS4_RECV, _(CO_FL_SOCK_RD_SH, |
218 | 0 | _(CO_FL_SOCK_WR_SH, _(CO_FL_ERROR, _(CO_FL_FDLESS, _(CO_FL_WAIT_L4_CONN, |
219 | 0 | _(CO_FL_WAIT_L6_CONN, _(CO_FL_SEND_PROXY, _(CO_FL_ACCEPT_PROXY, _(CO_FL_ACCEPT_CIP, |
220 | 0 | _(CO_FL_SSL_WAIT_HS, _(CO_FL_PRIVATE, _(CO_FL_RCVD_PROXY, _(CO_FL_SESS_IDLE, |
221 | 0 | _(CO_FL_XPRT_TRACKED |
222 | 0 | ))))))))))))))))))))))))))))); |
223 | 0 | /* epilogue */ |
224 | 0 | _(~0U); |
225 | 0 | return buf; |
226 | 0 | #undef _ |
227 | 0 | } Unexecuted instantiation: fuzz_cfg_parser.c:conn_show_flags Unexecuted instantiation: cfgparse.c:conn_show_flags Unexecuted instantiation: cli.c:conn_show_flags Unexecuted instantiation: connection.c:conn_show_flags Unexecuted instantiation: debug.c:conn_show_flags Unexecuted instantiation: dynbuf.c:conn_show_flags Unexecuted instantiation: errors.c:conn_show_flags Unexecuted instantiation: fd.c:conn_show_flags Unexecuted instantiation: filters.c:conn_show_flags Unexecuted instantiation: flt_http_comp.c:conn_show_flags Unexecuted instantiation: frontend.c:conn_show_flags Unexecuted instantiation: haproxy.c:conn_show_flags Unexecuted instantiation: http.c:conn_show_flags Unexecuted instantiation: http_ana.c:conn_show_flags Unexecuted instantiation: http_ext.c:conn_show_flags Unexecuted instantiation: http_htx.c:conn_show_flags Unexecuted instantiation: http_rules.c:conn_show_flags Unexecuted instantiation: lb_chash.c:conn_show_flags Unexecuted instantiation: lb_fas.c:conn_show_flags Unexecuted instantiation: lb_fwlc.c:conn_show_flags Unexecuted instantiation: lb_fwrr.c:conn_show_flags Unexecuted instantiation: lb_map.c:conn_show_flags Unexecuted instantiation: lb_ss.c:conn_show_flags Unexecuted instantiation: limits.c:conn_show_flags Unexecuted instantiation: listener.c:conn_show_flags Unexecuted instantiation: log.c:conn_show_flags Unexecuted instantiation: mailers.c:conn_show_flags Unexecuted instantiation: mworker.c:conn_show_flags Unexecuted instantiation: peers.c:conn_show_flags Unexecuted instantiation: pool.c:conn_show_flags Unexecuted instantiation: proto_rhttp.c:conn_show_flags Unexecuted instantiation: proto_sockpair.c:conn_show_flags Unexecuted instantiation: protocol.c:conn_show_flags Unexecuted instantiation: proxy.c:conn_show_flags Unexecuted instantiation: queue.c:conn_show_flags Unexecuted instantiation: resolvers.c:conn_show_flags Unexecuted instantiation: ring.c:conn_show_flags Unexecuted instantiation: sample.c:conn_show_flags Unexecuted instantiation: server.c:conn_show_flags Unexecuted instantiation: session.c:conn_show_flags Unexecuted instantiation: sink.c:conn_show_flags Unexecuted instantiation: sock.c:conn_show_flags Unexecuted instantiation: sock_inet.c:conn_show_flags Unexecuted instantiation: stats-html.c:conn_show_flags Unexecuted instantiation: stats.c:conn_show_flags Unexecuted instantiation: stconn.c:conn_show_flags Unexecuted instantiation: stick_table.c:conn_show_flags Unexecuted instantiation: stream.c:conn_show_flags Unexecuted instantiation: task.c:conn_show_flags Unexecuted instantiation: tcp_rules.c:conn_show_flags Unexecuted instantiation: tcpcheck.c:conn_show_flags Unexecuted instantiation: thread.c:conn_show_flags Unexecuted instantiation: tools.c:conn_show_flags Unexecuted instantiation: trace.c:conn_show_flags Unexecuted instantiation: uri_auth.c:conn_show_flags Unexecuted instantiation: vars.c:conn_show_flags Unexecuted instantiation: acl.c:conn_show_flags Unexecuted instantiation: action.c:conn_show_flags Unexecuted instantiation: activity.c:conn_show_flags Unexecuted instantiation: applet.c:conn_show_flags Unexecuted instantiation: backend.c:conn_show_flags Unexecuted instantiation: cache.c:conn_show_flags Unexecuted instantiation: cfgcond.c:conn_show_flags Unexecuted instantiation: cfgparse-global.c:conn_show_flags Unexecuted instantiation: cfgparse-listen.c:conn_show_flags Unexecuted instantiation: channel.c:conn_show_flags Unexecuted instantiation: check.c:conn_show_flags Unexecuted instantiation: compression.c:conn_show_flags Unexecuted instantiation: dgram.c:conn_show_flags Unexecuted instantiation: dns.c:conn_show_flags Unexecuted instantiation: dns_ring.c:conn_show_flags Unexecuted instantiation: event_hdl.c:conn_show_flags Unexecuted instantiation: extcheck.c:conn_show_flags Unexecuted instantiation: fcgi-app.c:conn_show_flags Unexecuted instantiation: guid.c:conn_show_flags Unexecuted instantiation: h1.c:conn_show_flags Unexecuted instantiation: http_fetch.c:conn_show_flags Unexecuted instantiation: mux_spop.c:conn_show_flags Unexecuted instantiation: pattern.c:conn_show_flags Unexecuted instantiation: payload.c:conn_show_flags Unexecuted instantiation: proto_tcp.c:conn_show_flags Unexecuted instantiation: stats-file.c:conn_show_flags Unexecuted instantiation: stats-json.c:conn_show_flags Unexecuted instantiation: stats-proxy.c:conn_show_flags Unexecuted instantiation: flt_spoe.c:conn_show_flags Unexecuted instantiation: h1_htx.c:conn_show_flags |
228 | | |
229 | | /* Possible connection error codes. |
230 | | * Warning: Do not reorder the codes, they are fetchable through the |
231 | | * "fc_err" sample fetch. If a new code is added, please add an error label |
232 | | * in conn_err_code_str and in the "fc_err_str" sample fetch documentation. |
233 | | */ |
234 | | enum { |
235 | | CO_ER_NONE, /* no error */ |
236 | | |
237 | | CO_ER_CONF_FDLIM, /* reached process's configured FD limitation */ |
238 | | CO_ER_PROC_FDLIM, /* reached process's FD limitation */ |
239 | | CO_ER_SYS_FDLIM, /* reached system's FD limitation */ |
240 | | CO_ER_SYS_MEMLIM, /* reached system buffers limitation */ |
241 | | CO_ER_NOPROTO, /* protocol not supported */ |
242 | | CO_ER_SOCK_ERR, /* other socket error */ |
243 | | |
244 | | CO_ER_PORT_RANGE, /* source port range exhausted */ |
245 | | CO_ER_CANT_BIND, /* can't bind to source address */ |
246 | | CO_ER_FREE_PORTS, /* no more free ports on the system */ |
247 | | CO_ER_ADDR_INUSE, /* local address already in use */ |
248 | | |
249 | | CO_ER_PRX_EMPTY, /* nothing received in PROXY protocol header */ |
250 | | CO_ER_PRX_ABORT, /* client abort during PROXY protocol header */ |
251 | | CO_ER_PRX_TIMEOUT, /* timeout while waiting for a PROXY header */ |
252 | | CO_ER_PRX_TRUNCATED, /* truncated PROXY protocol header */ |
253 | | CO_ER_PRX_NOT_HDR, /* not a PROXY protocol header */ |
254 | | CO_ER_PRX_BAD_HDR, /* bad PROXY protocol header */ |
255 | | CO_ER_PRX_BAD_PROTO, /* unsupported protocol in PROXY header */ |
256 | | |
257 | | CO_ER_CIP_EMPTY, /* nothing received in NetScaler Client IP header */ |
258 | | CO_ER_CIP_ABORT, /* client abort during NetScaler Client IP header */ |
259 | | CO_ER_CIP_TIMEOUT, /* timeout while waiting for a NetScaler Client IP header */ |
260 | | CO_ER_CIP_TRUNCATED, /* truncated NetScaler Client IP header */ |
261 | | CO_ER_CIP_BAD_MAGIC, /* bad magic number in NetScaler Client IP header */ |
262 | | CO_ER_CIP_BAD_PROTO, /* unsupported protocol in NetScaler Client IP header */ |
263 | | |
264 | | CO_ER_SSL_EMPTY, /* client closed during SSL handshake */ |
265 | | CO_ER_SSL_ABORT, /* client abort during SSL handshake */ |
266 | | CO_ER_SSL_TIMEOUT, /* timeout during SSL handshake */ |
267 | | CO_ER_SSL_TOO_MANY, /* too many SSL connections */ |
268 | | CO_ER_SSL_NO_MEM, /* no more memory to allocate an SSL connection */ |
269 | | CO_ER_SSL_RENEG, /* forbidden client renegotiation */ |
270 | | CO_ER_SSL_CA_FAIL, /* client cert verification failed in the CA chain */ |
271 | | CO_ER_SSL_CRT_FAIL, /* client cert verification failed on the certificate */ |
272 | | CO_ER_SSL_MISMATCH, /* Server presented an SSL certificate different from the configured one */ |
273 | | CO_ER_SSL_MISMATCH_SNI, /* Server presented an SSL certificate different from the expected one */ |
274 | | CO_ER_SSL_HANDSHAKE, /* SSL error during handshake */ |
275 | | CO_ER_SSL_HANDSHAKE_HB, /* SSL error during handshake with heartbeat present */ |
276 | | CO_ER_SSL_KILLED_HB, /* Stopped a TLSv1 heartbeat attack (CVE-2014-0160) */ |
277 | | CO_ER_SSL_NO_TARGET, /* unknown target (not client nor server) */ |
278 | | CO_ER_SSL_EARLY_FAILED, /* Server refused early data */ |
279 | | |
280 | | CO_ER_SOCKS4_SEND, /* SOCKS4 Proxy write error during handshake */ |
281 | | CO_ER_SOCKS4_RECV, /* SOCKS4 Proxy read error during handshake */ |
282 | | CO_ER_SOCKS4_DENY, /* SOCKS4 Proxy deny the request */ |
283 | | CO_ER_SOCKS4_ABORT, /* SOCKS4 Proxy handshake aborted by server */ |
284 | | |
285 | | CO_ER_SSL_FATAL, /* SSL fatal error during a SSL_read or SSL_write */ |
286 | | |
287 | | CO_ER_REVERSE, /* Error during reverse connect */ |
288 | | |
289 | | CO_ER_POLLERR, /* we only noticed POLLERR */ |
290 | | CO_ER_EREFUSED, /* ECONNREFUSED returned to recv/send */ |
291 | | CO_ER_ERESET, /* ECONNRESET returned to recv/send */ |
292 | | CO_ER_EUNREACH, /* ENETUNREACH returned to recv/send */ |
293 | | CO_ER_ENOMEM, /* ENOMEM returned to recv/send */ |
294 | | CO_ER_EBADF, /* EBADF returned to recv/send (serious bug) */ |
295 | | CO_ER_EFAULT, /* EFAULT returned to recv/send (serious bug) */ |
296 | | CO_ER_EINVAL, /* EINVAL returned to recv/send (serious bug) */ |
297 | | CO_ER_ENCONN, /* ENCONN returned to recv/send */ |
298 | | CO_ER_ENSOCK, /* ENSOCK returned to recv/send */ |
299 | | CO_ER_ENOBUFS, /* ENOBUFS returned to send */ |
300 | | CO_ER_EPIPE, /* EPIPE returned to send */ |
301 | | }; |
302 | | |
303 | | /* error return codes for accept_conn() */ |
304 | | enum { |
305 | | CO_AC_NONE = 0, /* no error, valid connection returned */ |
306 | | CO_AC_DONE, /* reached the end of the queue (typically EAGAIN) */ |
307 | | CO_AC_RETRY, /* late signal delivery or anything requiring the caller to try again */ |
308 | | CO_AC_YIELD, /* short-lived limitation that requires a short pause */ |
309 | | CO_AC_PAUSE, /* long-lived issue (resource/memory allocation error, paused FD) */ |
310 | | CO_AC_PERMERR, /* permanent, non-recoverable error (e.g. closed listener socket) */ |
311 | | }; |
312 | | |
313 | | /* source address settings for outgoing connections */ |
314 | | enum { |
315 | | /* Tproxy exclusive values from 0 to 7 */ |
316 | | CO_SRC_TPROXY_ADDR = 0x0001, /* bind to this non-local address when connecting */ |
317 | | CO_SRC_TPROXY_CIP = 0x0002, /* bind to the client's IP address when connecting */ |
318 | | CO_SRC_TPROXY_CLI = 0x0003, /* bind to the client's IP+port when connecting */ |
319 | | CO_SRC_TPROXY_DYN = 0x0004, /* bind to a dynamically computed non-local address */ |
320 | | CO_SRC_TPROXY_MASK = 0x0007, /* bind to a non-local address when connecting */ |
321 | | |
322 | | CO_SRC_BIND = 0x0008, /* bind to a specific source address when connecting */ |
323 | | }; |
324 | | |
325 | | /* flags that can be passed to xprt->rcv_buf() and mux->rcv_buf() */ |
326 | | enum { |
327 | | CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */ |
328 | | CO_RFL_BUF_FLUSH = 0x0002, /* Flush mux's buffers but don't read more data */ |
329 | | CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */ |
330 | | CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */ |
331 | | CO_RFL_BUF_NOT_STUCK = 0x0010, /* Buffer is not stuck. Optims are possible during data copy */ |
332 | | CO_RFL_MAY_SPLICE = 0x0020, /* The producer can use the kernel splicing */ |
333 | | CO_RFL_TRY_HARDER = 0x0040, /* Try to read till READ0 even on short reads */ |
334 | | }; |
335 | | |
336 | | /* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */ |
337 | | enum { |
338 | | CO_SFL_MSG_MORE = 0x0001, /* More data to come afterwards */ |
339 | | CO_SFL_STREAMER = 0x0002, /* Producer is continuously streaming data */ |
340 | | CO_SFL_LAST_DATA = 0x0003, /* Sent data are the last ones, shutdown is pending */ |
341 | | }; |
342 | | |
343 | | /* known transport layers (for ease of lookup) */ |
344 | | enum { |
345 | | XPRT_RAW = 0, |
346 | | XPRT_SSL = 1, |
347 | | XPRT_HANDSHAKE = 2, |
348 | | XPRT_QUIC = 3, |
349 | | XPRT_ENTRIES /* must be last one */ |
350 | | }; |
351 | | |
352 | | /* MUX-specific flags */ |
353 | | enum { |
354 | | MX_FL_NONE = 0x00000000, |
355 | | MX_FL_HTX = 0x00000001, /* set if it is an HTX multiplexer */ |
356 | | MX_FL_HOL_RISK = 0x00000002, /* set if the protocol is subject the to head-of-line blocking on server */ |
357 | | MX_FL_NO_UPG = 0x00000004, /* set if mux does not support any upgrade */ |
358 | | MX_FL_FRAMED = 0x00000008, /* mux working on top of a framed transport layer (QUIC) */ |
359 | | MX_FL_REVERSABLE = 0x00000010, /* mux supports connection reversal */ |
360 | | }; |
361 | | |
362 | | /* PROTO token registration */ |
363 | | enum proto_proxy_mode { |
364 | | PROTO_MODE_NONE = 0, |
365 | | PROTO_MODE_TCP = 1 << 0, // must not be changed! |
366 | | PROTO_MODE_HTTP = 1 << 1, // must not be changed! |
367 | | PROTO_MODE_SPOP = 1 << 2, // must not be changed! |
368 | | PROTO_MODE_ANY = PROTO_MODE_TCP | PROTO_MODE_HTTP | PROTO_MODE_SPOP, |
369 | | }; |
370 | | |
371 | | enum proto_proxy_side { |
372 | | PROTO_SIDE_NONE = 0, |
373 | | PROTO_SIDE_FE = 1, // same as PR_CAP_FE |
374 | | PROTO_SIDE_BE = 2, // same as PR_CAP_BE |
375 | | PROTO_SIDE_BOTH = PROTO_SIDE_FE | PROTO_SIDE_BE, |
376 | | }; |
377 | | |
378 | | /* ctl command used by mux->ctl() */ |
379 | | enum mux_ctl_type { |
380 | | MUX_CTL_STATUS, /* Expects an int as output, sets it to a combination of MUX_CTL_STATUS flags */ |
381 | | MUX_CTL_EXIT_STATUS, /* Expects an int as output, sets the mux exist/error/http status, if known or 0 */ |
382 | | MUX_CTL_REVERSE_CONN, /* Notify about an active reverse connection accepted. */ |
383 | | MUX_CTL_SUBS_RECV, /* Notify the mux it must wait for read events again */ |
384 | | MUX_CTL_GET_GLITCHES, /* returns number of glitches on the connection */ |
385 | | MUX_CTL_GET_NBSTRM, /* Return the current number of streams on the connection */ |
386 | | MUX_CTL_GET_MAXSTRM, /* Return the max number of streams supported by the connection */ |
387 | | MUX_CTL_TEVTS, /* Return the termination events log of the mux connection */ |
388 | | }; |
389 | | |
390 | | /* sctl command used by mux->sctl() */ |
391 | | enum mux_sctl_type { |
392 | | MUX_SCTL_SID, /* Return the mux stream ID as output, as a signed 64bits integer */ |
393 | | MUX_SCTL_DBG_STR, /* takes a mux_sctl_dbg_str_ctx argument, reads flags and returns debug info */ |
394 | | MUX_SCTL_TEVTS, /* Return the termination events log of the mux stream */ |
395 | | }; |
396 | | |
397 | 0 | #define MUX_SCTL_DBG_STR_L_MUXS 0x00000001 // info from mux stream |
398 | 0 | #define MUX_SCTL_DBG_STR_L_MUXC 0x00000002 // info from mux connection |
399 | | #define MUX_SCTL_DBG_STR_L_XPRT 0x00000004 // info from xprt layer |
400 | 0 | #define MUX_SCTL_DBG_STR_L_CONN 0x00000008 // info from struct connection layer |
401 | | #define MUX_SCTL_DBG_STR_L_SOCK 0x00000010 // info from socket layer (quic_conn as well) |
402 | | |
403 | | |
404 | | /* response for ctl MUX_STATUS */ |
405 | 0 | #define MUX_STATUS_READY (1 << 0) |
406 | | |
407 | | enum mux_exit_status { |
408 | | MUX_ES_SUCCESS, /* Success */ |
409 | | MUX_ES_INVALID_ERR, /* invalid input */ |
410 | | MUX_ES_TOUT_ERR, /* timeout */ |
411 | | MUX_ES_NOTIMPL_ERR, /* not-implemented error */ |
412 | | MUX_ES_INTERNAL_ERR, /* internal error */ |
413 | | MUX_ES_UNKNOWN /* unknown status (must be the last) */ |
414 | | }; |
415 | | |
416 | | /* socks4 response length */ |
417 | 0 | #define SOCKS4_HS_RSP_LEN 8 |
418 | | |
419 | | /* socks4 upstream proxy definitions */ |
420 | | struct socks4_request { |
421 | | uint8_t version; /* SOCKS version number, 1 byte, must be 0x04 for this version */ |
422 | | uint8_t command; /* 0x01 = establish a TCP/IP stream connection */ |
423 | | uint16_t port; /* port number, 2 bytes (in network byte order) */ |
424 | | uint32_t ip; /* IP address, 4 bytes (in network byte order) */ |
425 | | char user_id[8]; /* the user ID string, variable length, terminated with a null (0x00); Using "HAProxy\0" */ |
426 | | }; |
427 | | |
428 | | /* A connection handle is how we differentiate two connections on the lower |
429 | | * layers. It usually is a file descriptor but can be a connection id. The |
430 | | * CO_FL_FDLESS flag indicates which one is relevant. |
431 | | */ |
432 | | union conn_handle { |
433 | | struct quic_conn *qc; /* Only present if this connection is a QUIC one (CO_FL_FDLESS=1) */ |
434 | | int fd; /* file descriptor, for regular sockets (CO_FL_FDLESS=0) */ |
435 | | }; |
436 | | |
437 | | enum xprt_capabilities { |
438 | | XPRT_CAN_SPLICE, |
439 | | }; |
440 | | |
441 | | enum xprt_splice_cap { |
442 | | XPRT_CONN_CAN_NOT_SPLICE, /* This connection can't, and won't ever be able to splice */ |
443 | | XPRT_CONN_COULD_SPLICE, /* This connection can't splice, but may later */ |
444 | | XPRT_CONN_CAN_SPLICE /* This connection can splice */ |
445 | | }; |
446 | | |
447 | | /* xprt_ops describes transport-layer operations for a connection. They |
448 | | * generally run over a socket-based control layer, but not always. Some |
449 | | * of them are used for data transfer with the upper layer (rcv_*, snd_*) |
450 | | * and the other ones are used to setup and release the transport layer. |
451 | | */ |
452 | | struct xprt_ops { |
453 | | size_t (*rcv_buf)(struct connection *conn, void *xprt_ctx, struct buffer *buf, size_t count, void *msg_control, size_t *msg_controllen, int flags); /* recv callback */ |
454 | | size_t (*snd_buf)(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, void *msg_control, size_t msg_controllen, int flags); /* send callback */ |
455 | | int (*rcv_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */ |
456 | | int (*snd_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count); /* send-to-pipe callback */ |
457 | | void (*shutr)(struct connection *conn, void *xprt_ctx, int); /* shutr function */ |
458 | | void (*shutw)(struct connection *conn, void *xprt_ctx, int); /* shutw function */ |
459 | | void (*close)(struct connection *conn, void *xprt_ctx); /* close the transport layer */ |
460 | | int (*init)(struct connection *conn, void **ctx); /* initialize the transport layer */ |
461 | | int (*start)(struct connection *conn, void *ctx); /* Start the transport layer, if needed */ |
462 | | int (*prepare_bind_conf)(struct bind_conf *conf); /* prepare a whole bind_conf */ |
463 | | void (*destroy_bind_conf)(struct bind_conf *conf); /* destroy a whole bind_conf */ |
464 | | int (*prepare_srv)(struct server *srv); /* prepare a server context */ |
465 | | void (*destroy_srv)(struct server *srv); /* destroy a server context */ |
466 | | int (*get_alpn)(const struct connection *conn, void *xprt_ctx, const char **str, int *len); /* get application layer name */ |
467 | | int (*takeover)(struct connection *conn, void *xprt_ctx, int orig_tid, int release); /* Let the xprt know the fd have been taken over */ |
468 | | void (*set_idle)(struct connection *conn, void *xprt_ctx); /* notify the xprt that the connection becomes idle. implies set_used. */ |
469 | | void (*set_used)(struct connection *conn, void *xprt_ctx); /* notify the xprt that the connection leaves idle. implies set_idle. */ |
470 | | char name[8]; /* transport layer name, zero-terminated */ |
471 | | int (*subscribe)(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* Subscribe <es> to events, such as "being able to send" */ |
472 | | int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* Unsubscribe <es> from events */ |
473 | | int (*remove_xprt)(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx); /* Remove an xprt from the connection, used by temporary xprt such as the handshake one */ |
474 | | int (*add_xprt)(struct connection *conn, void *xprt_ctx, void *toadd_ctx, const struct xprt_ops *toadd_ops, void **oldxprt_ctx, const struct xprt_ops **oldxprt_ops); /* Add a new XPRT as the new xprt, and return the old one */ |
475 | | struct ssl_sock_ctx *(*get_ssl_sock_ctx)(struct connection *); /* retrieve the ssl_sock_ctx in use, or NULL if none */ |
476 | | int (*show_fd)(struct buffer *, const struct connection *, const void *ctx); /* append some data about xprt for "show fd"; returns non-zero if suspicious */ |
477 | | void (*dump_info)(struct buffer *, const struct connection *); |
478 | | /* |
479 | | * Returns the value for various capabilities. |
480 | | * Returns 0 if the capability is known, with the actual value in arg, |
481 | | * or -1 otherwise |
482 | | */ |
483 | | int (*get_capability)(struct connection *connection, void *xprt_ctx, enum xprt_capabilities, void *arg); |
484 | | }; |
485 | | |
486 | | /* mux_ops describes the mux operations, which are to be performed at the |
487 | | * connection level after data are exchanged with the transport layer in order |
488 | | * to propagate them to streams. The <init> function will automatically be |
489 | | * called once the mux is instantiated by the connection's owner at the end |
490 | | * of a transport handshake, when it is about to transfer data and the data |
491 | | * layer is not ready yet. |
492 | | */ |
493 | | struct mux_ops { |
494 | | int (*init)(struct connection *conn, struct proxy *prx, struct session *sess, struct buffer *input); /* early initialization */ |
495 | | int (*wake)(struct connection *conn); /* mux-layer callback to report activity, mandatory */ |
496 | | size_t (*rcv_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); /* Called from the upper layer to get data */ |
497 | | size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); /* Called from the upper layer to send data */ |
498 | | size_t (*nego_fastfwd)(struct stconn *sc, struct buffer *input, size_t count, unsigned int may_splice); /* Callback to fill the SD iobuf */ |
499 | | size_t (*done_fastfwd)(struct stconn *sc); /* Callback to terminate fast data forwarding */ |
500 | | int (*fastfwd)(struct stconn *sc, unsigned int count, unsigned int flags); /* Callback to init fast data forwarding */ |
501 | | int (*resume_fastfwd)(struct stconn *sc, unsigned int flags); /* Callback to resume fast data forwarding */ |
502 | | void (*shut)(struct stconn *sc, unsigned int mode, struct se_abort_info *reason); /* shutdown function */ |
503 | | |
504 | | int (*attach)(struct connection *conn, struct sedesc *, struct session *sess); /* attach a stconn to an outgoing connection */ |
505 | | struct stconn *(*get_first_sc)(const struct connection *); /* retrieves any valid stconn from this connection */ |
506 | | void (*detach)(struct sedesc *); /* Detach an stconn from the stdesc from an outgoing connection, when the request is done */ |
507 | | int (*show_fd)(struct buffer *, struct connection *); /* append some data about connection into chunk for "show fd"; returns non-zero if suspicious */ |
508 | | int (*show_sd)(struct buffer *, struct sedesc *, const char *pfx); /* append some data about the mux stream into chunk for "show sess"; returns non-zero if suspicious */ |
509 | | int (*subscribe)(struct stconn *sc, int event_type, struct wait_event *es); /* Subscribe <es> to events, such as "being able to send" */ |
510 | | int (*unsubscribe)(struct stconn *sc, int event_type, struct wait_event *es); /* Unsubscribe <es> from events */ |
511 | | int (*sctl)(struct stconn *sc, enum mux_sctl_type mux_sctl, void *arg); /* Provides information about the mux stream */ |
512 | | int (*avail_streams)(struct connection *conn); /* Returns the number of streams still available for a connection */ |
513 | | int (*used_streams)(struct connection *conn); /* Returns the number of streams in use on a connection. */ |
514 | | void (*destroy)(void *ctx); /* Let the mux know one of its users left, so it may have to disappear */ |
515 | | int (*ctl)(struct connection *conn, enum mux_ctl_type mux_ctl, void *arg); /* Provides information about the mux connection */ |
516 | | |
517 | | /* Attempts to migrate <conn> from <orig_tid> to the current thread. If |
518 | | * <release> is true, it will be destroyed immediately after by caller. |
519 | | */ |
520 | | int (*takeover)(struct connection *conn, int orig_tid, int release); |
521 | | |
522 | | unsigned int flags; /* some flags characterizing the mux's capabilities (MX_FL_*) */ |
523 | | char name[8]; /* mux layer name, zero-terminated */ |
524 | | }; |
525 | | |
526 | | /* list of frontend connections. Used to call mux wake operation on soft-stop |
527 | | * to close idling connections. |
528 | | */ |
529 | | struct mux_stopping_data { |
530 | | struct list list; /* list of registered frontend connections */ |
531 | | struct task *task; /* task woken up on soft-stop */ |
532 | | }; |
533 | | |
534 | | struct my_tcphdr { |
535 | | uint16_t source; |
536 | | uint16_t dest; |
537 | | }; |
538 | | |
539 | | /* a connection source profile defines all the parameters needed to properly |
540 | | * bind an outgoing connection for a server or proxy. |
541 | | */ |
542 | | struct conn_src { |
543 | | unsigned int opts; /* CO_SRC_* */ |
544 | | int iface_len; /* bind interface name length */ |
545 | | char *iface_name; /* bind interface name or NULL */ |
546 | | struct port_range *sport_range; /* optional per-server TCP source ports */ |
547 | | struct sockaddr_storage source_addr; /* the address to which we want to bind for connect() */ |
548 | | #if defined(CONFIG_HAP_TRANSPARENT) |
549 | | struct sockaddr_storage tproxy_addr; /* non-local address we want to bind to for connect() */ |
550 | | char *bind_hdr_name; /* bind to this header name if defined */ |
551 | | int bind_hdr_len; /* length of the name of the header above */ |
552 | | int bind_hdr_occ; /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */ |
553 | | #endif |
554 | | }; |
555 | | |
556 | | /* Hash header flag reflecting the input parameters present |
557 | | * CAUTION! Always update CONN_HASH_PARAMS_TYPE_COUNT when adding a new entry. |
558 | | */ |
559 | | enum conn_hash_params_t { |
560 | | CONN_HASH_PARAMS_TYPE_NAME = 0x1, |
561 | | CONN_HASH_PARAMS_TYPE_DST_ADDR = 0x2, |
562 | | CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4, |
563 | | CONN_HASH_PARAMS_TYPE_SRC_ADDR = 0x8, |
564 | | CONN_HASH_PARAMS_TYPE_SRC_PORT = 0x10, |
565 | | CONN_HASH_PARAMS_TYPE_PROXY = 0x20, |
566 | | CONN_HASH_PARAMS_TYPE_MARK_TOS = 0x40, |
567 | | }; |
568 | 0 | #define CONN_HASH_PARAMS_TYPE_COUNT 7 |
569 | | |
570 | | #define CONN_HASH_PAYLOAD_LEN \ |
571 | 0 | (((sizeof(((struct conn_hash_node *)0)->key)) * 8) - CONN_HASH_PARAMS_TYPE_COUNT) |
572 | | |
573 | | #define CONN_HASH_GET_PAYLOAD(hash) \ |
574 | 0 | (((hash) << CONN_HASH_PARAMS_TYPE_COUNT) >> CONN_HASH_PARAMS_TYPE_COUNT) |
575 | | |
576 | | /* To avoid overflow, dynamically sized parameters must be pre-hashed. Their |
577 | | * hashed will then be reused as input for the generation of the final |
578 | | * connection hash. |
579 | | */ |
580 | | struct conn_hash_params { |
581 | | uint64_t name_prehash; |
582 | | uint64_t proxy_prehash; |
583 | | uint64_t mark_tos_prehash; |
584 | | void *target; |
585 | | struct sockaddr_storage *src_addr; |
586 | | struct sockaddr_storage *dst_addr; |
587 | | }; |
588 | | |
589 | | /* |
590 | | * This structure describes an TLV entry consisting of its type |
591 | | * and corresponding payload. This can be used to construct a list |
592 | | * from which arbitrary TLV payloads can be fetched. |
593 | | * It might be possible to embed the 'tlv struct' here in the future. |
594 | | */ |
595 | | struct conn_tlv_list { |
596 | | struct list list; |
597 | | unsigned short len; // 65535 should be more than enough! |
598 | | unsigned char type; |
599 | | char value[0]; |
600 | | } __attribute__((packed)); |
601 | | |
602 | | |
603 | | /* node for backend connection in the idle trees for http-reuse |
604 | | * A connection is identified by a hash generated from its specific parameters |
605 | | */ |
606 | | struct conn_hash_node { |
607 | | struct ceb_node node; /* indexes the hashing key for safe/idle/avail */ |
608 | | uint64_t key; /* the hashing key, also used by session-owned */ |
609 | | }; |
610 | | |
611 | | /* This structure describes a connection with its methods and data. |
612 | | * A connection may be performed to proxy or server via a local or remote |
613 | | * socket, and can also be made to an internal applet. It can support |
614 | | * several transport schemes (raw, ssl, ...). It can support several |
615 | | * connection control schemes, generally a protocol for socket-oriented |
616 | | * connections, but other methods for applets. |
617 | | */ |
618 | | struct connection { |
619 | | /* first cache line */ |
620 | | enum obj_type obj_type; /* differentiates connection from applet context */ |
621 | | unsigned char err_code; /* CO_ER_* */ |
622 | | signed short send_proxy_ofs; /* <0 = offset to (re)send from the end, >0 = send all (reused for SOCKS4) */ |
623 | | unsigned int flags; /* CO_FL_* */ |
624 | | const struct protocol *ctrl; /* operations at the socket layer */ |
625 | | const struct xprt_ops *xprt; /* operations at the transport layer */ |
626 | | const struct mux_ops *mux; /* mux layer operations. Must be set before xprt->init() */ |
627 | | void *xprt_ctx; /* general purpose pointer, initialized to NULL */ |
628 | | void *ctx; /* highest level context (usually the mux), initialized to NULL */ |
629 | | void *owner; /* pointer to the owner session, or NULL */ |
630 | | enum obj_type *target; /* the target to connect to (server, proxy, applet, ...) */ |
631 | | |
632 | | /* second cache line */ |
633 | | struct wait_event *subs; /* Task to wake when awaited events are ready */ |
634 | | union { |
635 | | /* Backend connections only */ |
636 | | struct { |
637 | | struct mt_list toremove_list; /* list element when idle connection is ready to be purged */ |
638 | | struct list idle_list; /* list element for idle connection in server idle list */ |
639 | | struct list sess_el; /* used by private connections, list elem into session */ |
640 | | }; |
641 | | /* Frontend connections only */ |
642 | | struct list stopping_list; /* attach point in mux stopping list */ |
643 | | }; |
644 | | union conn_handle handle; /* connection handle at the socket layer */ |
645 | | const struct netns_entry *proxy_netns; |
646 | | |
647 | | /* third cache line and beyond */ |
648 | | void (*destroy_cb)(struct connection *conn); /* callback to notify of imminent death of the connection */ |
649 | | struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */ |
650 | | struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */ |
651 | | struct list tlv_list; /* list of TLVs received via PROXYv2 */ |
652 | | |
653 | | /* used to identify a backend connection for http-reuse, |
654 | | * thus only present if conn.target is of type OBJ_TYPE_SERVER |
655 | | */ |
656 | | struct conn_hash_node hash_node; |
657 | | |
658 | | /* Members used if connection must be reversed. */ |
659 | | struct { |
660 | | enum obj_type *target; /* Listener for active reverse, server for passive. */ |
661 | | struct buffer name; /* Only used for passive reverse. Used as SNI when connection added to server idle pool. */ |
662 | | } reverse; |
663 | | |
664 | | uint64_t sni_hash; /* Hash of the SNI. Used to cache the TLS session and try to reuse it. set to 0 is there is no SNI */ |
665 | | uint32_t term_evts_log; /* Termination events log: first 4 events reported from fd, handshake or xprt */ |
666 | | uint32_t mark; /* set network mark, if CO_FL_OPT_MARK is set */ |
667 | | uint8_t tos; /* set ip tos, if CO_FL_OPT_TOS is set */ |
668 | | }; |
669 | | |
670 | | struct mux_proto_list { |
671 | | const struct ist token; /* token name and length. Empty is catch-all */ |
672 | | enum proto_proxy_mode mode; |
673 | | enum proto_proxy_side side; |
674 | | const struct mux_ops *mux; |
675 | | const char *alpn; /* Default alpn to set by default when the mux protocol is forced (optional, in binary form) */ |
676 | | struct list list; |
677 | | }; |
678 | | |
679 | | /* proxy protocol stuff below */ |
680 | | |
681 | | /* proxy protocol v2 definitions */ |
682 | 0 | #define PP2_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" |
683 | 0 | #define PP2_SIGNATURE_LEN 12 |
684 | 0 | #define PP2_HEADER_LEN 16 |
685 | | |
686 | | /* ver_cmd byte */ |
687 | 0 | #define PP2_CMD_LOCAL 0x00 |
688 | 0 | #define PP2_CMD_PROXY 0x01 |
689 | 0 | #define PP2_CMD_MASK 0x0F |
690 | | |
691 | 0 | #define PP2_VERSION 0x20 |
692 | 0 | #define PP2_VERSION_MASK 0xF0 |
693 | | |
694 | | /* fam byte */ |
695 | 0 | #define PP2_TRANS_UNSPEC 0x00 |
696 | 0 | #define PP2_TRANS_STREAM 0x01 |
697 | | #define PP2_TRANS_DGRAM 0x02 |
698 | | #define PP2_TRANS_MASK 0x0F |
699 | | |
700 | 0 | #define PP2_FAM_UNSPEC 0x00 |
701 | 0 | #define PP2_FAM_INET 0x10 |
702 | 0 | #define PP2_FAM_INET6 0x20 |
703 | | #define PP2_FAM_UNIX 0x30 |
704 | | #define PP2_FAM_MASK 0xF0 |
705 | | |
706 | 0 | #define PP2_ADDR_LEN_UNSPEC (0) |
707 | 0 | #define PP2_ADDR_LEN_INET (4 + 4 + 2 + 2) |
708 | 0 | #define PP2_ADDR_LEN_INET6 (16 + 16 + 2 + 2) |
709 | | #define PP2_ADDR_LEN_UNIX (108 + 108) |
710 | | |
711 | 0 | #define PP2_HDR_LEN_UNSPEC (PP2_HEADER_LEN + PP2_ADDR_LEN_UNSPEC) |
712 | 0 | #define PP2_HDR_LEN_INET (PP2_HEADER_LEN + PP2_ADDR_LEN_INET) |
713 | 0 | #define PP2_HDR_LEN_INET6 (PP2_HEADER_LEN + PP2_ADDR_LEN_INET6) |
714 | | #define PP2_HDR_LEN_UNIX (PP2_HEADER_LEN + PP2_ADDR_LEN_UNIX) |
715 | | |
716 | 0 | #define PP2_TYPE_ALPN 0x01 |
717 | 0 | #define PP2_TYPE_AUTHORITY 0x02 |
718 | 0 | #define PP2_TYPE_CRC32C 0x03 |
719 | 0 | #define PP2_TYPE_NOOP 0x04 |
720 | 0 | #define PP2_TYPE_UNIQUE_ID 0x05 |
721 | 0 | #define PP2_TYPE_SSL 0x20 |
722 | 0 | #define PP2_SUBTYPE_SSL_VERSION 0x21 |
723 | 0 | #define PP2_SUBTYPE_SSL_CN 0x22 |
724 | 0 | #define PP2_SUBTYPE_SSL_CIPHER 0x23 |
725 | 0 | #define PP2_SUBTYPE_SSL_SIG_ALG 0x24 |
726 | 0 | #define PP2_SUBTYPE_SSL_KEY_ALG 0x25 |
727 | 0 | #define PP2_TYPE_NETNS 0x30 |
728 | | |
729 | | #define PP2_CLIENT_SSL 0x01 |
730 | | #define PP2_CLIENT_CERT_CONN 0x02 |
731 | | #define PP2_CLIENT_CERT_SESS 0x04 |
732 | | |
733 | 0 | #define PP2_CRC32C_LEN 4 /* Length of a CRC32C TLV value */ |
734 | | |
735 | 0 | #define TLV_HEADER_SIZE 3 |
736 | | |
737 | 0 | #define HA_PP2_AUTHORITY_MAX 255 /* Maximum length of an authority TLV */ |
738 | 0 | #define HA_PP2_TLV_VALUE_128 128 /* E.g., accommodate unique IDs (128 B) */ |
739 | 0 | #define HA_PP2_TLV_VALUE_256 256 /* E.g., accommodate authority TLVs (currently, <= 255 B) */ |
740 | | #define HA_PP2_MAX_ALLOC 1024 /* Maximum TLV value for PPv2 to prevent DoS */ |
741 | | |
742 | | struct proxy_hdr_v2 { |
743 | | uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */ |
744 | | uint8_t ver_cmd; /* protocol version and command */ |
745 | | uint8_t fam; /* protocol family and transport */ |
746 | | uint16_t len; /* number of following bytes part of the header */ |
747 | | union { |
748 | | struct { /* for TCP/UDP over IPv4, len = 12 */ |
749 | | uint32_t src_addr; |
750 | | uint32_t dst_addr; |
751 | | uint16_t src_port; |
752 | | uint16_t dst_port; |
753 | | } ip4; |
754 | | struct { /* for TCP/UDP over IPv6, len = 36 */ |
755 | | uint8_t src_addr[16]; |
756 | | uint8_t dst_addr[16]; |
757 | | uint16_t src_port; |
758 | | uint16_t dst_port; |
759 | | } ip6; |
760 | | struct { /* for AF_UNIX sockets, len = 216 */ |
761 | | uint8_t src_addr[108]; |
762 | | uint8_t dst_addr[108]; |
763 | | } unx; |
764 | | } addr; |
765 | | }; |
766 | | |
767 | | struct tlv { |
768 | | uint8_t type; |
769 | | uint8_t length_hi; |
770 | | uint8_t length_lo; |
771 | | uint8_t value[0]; // WT: don't use VAR_ARRAY here, it's an end of struct marker |
772 | | }__attribute__((packed)); |
773 | | |
774 | | struct tlv_ssl { |
775 | | struct tlv tlv; |
776 | | uint8_t client; |
777 | | uint32_t verify; |
778 | | uint8_t sub_tlv[VAR_ARRAY]; |
779 | | }__attribute__((packed)); |
780 | | |
781 | | /* context for a MUX_SCTL_DBG_STR call */ |
782 | | union mux_sctl_dbg_str_ctx { |
783 | | struct { |
784 | | uint debug_flags; // union of MUX_SCTL_DBG_STR_L_* |
785 | | } arg; // sctl argument for the call |
786 | | struct { |
787 | | struct buffer buf; |
788 | | } ret; // sctl return contents |
789 | | }; |
790 | | |
791 | | /* This structure is used to manage idle connections, their locking, and the |
792 | | * list of such idle connections to be removed. It is per-thread and must be |
793 | | * accessible from foreign threads. |
794 | | */ |
795 | | struct idle_conns { |
796 | | struct mt_list toremove_conns; |
797 | | struct task *cleanup_task; |
798 | | __decl_thread(HA_SPINLOCK_T idle_conns_lock); |
799 | | } THREAD_ALIGNED(); |
800 | | |
801 | | |
802 | | /* Termination events logs: |
803 | | * Each event is stored on 8 bits: 4 bits bor the event location and |
804 | | * 4 bits for the event type. |
805 | | */ |
806 | | |
807 | | /* Locations for termination event logs (4-bits). But only 7 locations are |
808 | | * supported because 1 bit is reserved to distinguish frontend to backend |
809 | | * events: the msb is set to 1 for backend events. |
810 | | */ |
811 | | enum term_event_loc { |
812 | | tevt_loc_fd = 1, |
813 | | tevt_loc_hs = 2, |
814 | | tevt_loc_xprt = 3, |
815 | | tevt_loc_muxc = 4, |
816 | | tevt_loc_se = 5, |
817 | | tevt_loc_strm = 6, |
818 | | }; |
819 | | |
820 | | /* Types for termination event logs (4-bits) per location */ |
821 | | enum fd_term_event_type { |
822 | | fd_tevt_type_shutw = 1, |
823 | | fd_tevt_type_shutr = 2, |
824 | | fd_tevt_type_rcv_err = 3, |
825 | | fd_tevt_type_snd_err = 4, |
826 | | /* unused: 5, 6 */ |
827 | | fd_tevt_type_connect_err = 7, |
828 | | fd_tevt_type_intercepted = 8, |
829 | | |
830 | | fd_tevt_type_connect_poll_err = 9, |
831 | | fd_tevt_type_poll_err = 10, |
832 | | fd_tevt_type_poll_hup = 11, |
833 | | }; |
834 | | |
835 | | enum hs_term_event_type { |
836 | | /* unused: 1, 2, 3 */ |
837 | | hs_tevt_type_snd_err = 4, |
838 | | hs_tevt_type_truncated_shutr = 5, |
839 | | hs_tevt_type_truncated_rcv_err = 6, |
840 | | }; |
841 | | |
842 | | enum xprt_term_event_type { |
843 | | xprt_tevt_type_shutw = 1, |
844 | | xprt_tevt_type_shutr = 2, |
845 | | xprt_tevt_type_rcv_err = 3, |
846 | | xprt_tevt_type_snd_err = 4, |
847 | | }; |
848 | | |
849 | | enum muxc_term_event_type { |
850 | | muxc_tevt_type_shutw = 1, |
851 | | muxc_tevt_type_shutr = 2, |
852 | | muxc_tevt_type_rcv_err = 3, |
853 | | muxc_tevt_type_snd_err = 4, |
854 | | muxc_tevt_type_truncated_shutr = 5, |
855 | | muxc_tevt_type_truncated_rcv_err= 6, |
856 | | |
857 | | muxc_tevt_type_tout = 7, |
858 | | muxc_tevt_type_goaway_rcvd = 8, |
859 | | muxc_tevt_type_proto_err = 9, |
860 | | muxc_tevt_type_internal_err = 10, |
861 | | muxc_tevt_type_other_err = 11, |
862 | | muxc_tevt_type_graceful_shut = 12, |
863 | | }; |
864 | | |
865 | | enum se_term_event_type { |
866 | | se_tevt_type_shutw = 1, |
867 | | se_tevt_type_eos = 2, |
868 | | se_tevt_type_rcv_err = 3, |
869 | | se_tevt_type_snd_err = 4, |
870 | | se_tevt_type_truncated_eos = 5, |
871 | | se_tevt_type_truncated_rcv_err= 6, |
872 | | /* unused: 7 */ |
873 | | se_tevt_type_rst_rcvd = 8, |
874 | | se_tevt_type_proto_err = 9, |
875 | | se_tevt_type_internal_err = 10, |
876 | | se_tevt_type_other_err = 11, |
877 | | se_tevt_type_cancelled = 12, |
878 | | }; |
879 | | |
880 | | enum strm_term_event_type { |
881 | | strm_tevt_type_shutw = 1, |
882 | | strm_tevt_type_eos = 2, |
883 | | strm_tevt_type_rcv_err = 3, |
884 | | strm_tevt_type_snd_err = 4, |
885 | | strm_tevt_type_truncated_eos = 5, |
886 | | strm_tevt_type_truncated_rcv_err= 6, |
887 | | |
888 | | strm_tevt_type_tout = 7, |
889 | | strm_tevt_type_intercepted = 8, |
890 | | |
891 | | strm_tevt_type_proto_err = 9, |
892 | | strm_tevt_type_internal_err = 10, |
893 | | strm_tevt_type_other_err = 11, |
894 | | strm_tevt_type_aborted = 12, |
895 | | }; |
896 | | |
897 | | #endif /* _HAPROXY_CONNECTION_T_H */ |
898 | | |
899 | | /* |
900 | | * Local variables: |
901 | | * c-indent-level: 8 |
902 | | * c-basic-offset: 8 |
903 | | * End: |
904 | | */ |