blob: 7205b2c4c565089fb743eef9b5c9ce196aba9c15 [file] [log] [blame]
Willy Tarreau59f98392012-07-06 14:13:49 +02001/*
2 * include/proto/connection.h
3 * This file contains connection function prototypes
4 *
5 * Copyright (C) 2000-2012 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 _PROTO_CONNECTION_H
23#define _PROTO_CONNECTION_H
24
25#include <common/config.h>
26#include <types/connection.h>
27
28/* I/O callback for fd-based connections. It calls the read/write handlers
Willy Tarreauafad0e02012-08-09 14:45:22 +020029 * provided by the connection's sock_ops. Returns 0.
Willy Tarreau59f98392012-07-06 14:13:49 +020030 */
31int conn_fd_handler(int fd);
32
Willy Tarreau8b117082012-08-06 15:06:49 +020033/* Calls the close() function of the data layer if any */
34static inline void conn_data_close(struct connection *conn)
35{
Willy Tarreau4a36b562012-08-06 19:31:45 +020036 if (conn->data && conn->data->close)
Willy Tarreau8b117082012-08-06 15:06:49 +020037 conn->data->close(conn);
38}
39
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020040/* set polling depending on the change between the CURR part of the
41 * flags and the new flags in connection C. The connection flags are
42 * updated with the new flags at the end of the operation. Only the bits
43 * relevant to CO_FL_CURR_* from <flags> are considered.
44 */
45void conn_set_polling(struct connection *c, unsigned int new);
46
47/* update polling depending on the change between the CURR part of the
48 * flags and the DATA part of the flags in connection C. The connection
49 * is assumed to already be in the data phase.
50 */
51static inline void conn_update_data_polling(struct connection *c)
52{
53 conn_set_polling(c, c->flags << 8);
54}
55
56/* update polling depending on the change between the CURR part of the
57 * flags and the SOCK part of the flags in connection C. The connection
58 * is assumed to already be in the handshake phase.
59 */
60static inline void conn_update_sock_polling(struct connection *c)
61{
62 conn_set_polling(c, c->flags << 4);
63}
64
65/* returns non-zero if data flags from c->flags changes from what is in the
66 * current section of c->flags.
67 */
68static inline unsigned int conn_data_polling_changes(const struct connection *c)
69{
70 return ((c->flags << 8) ^ c->flags) & 0xF0000000;
71}
72
73/* returns non-zero if sock flags from c->flags changes from what is in the
74 * current section of c->flags.
75 */
76static inline unsigned int conn_sock_polling_changes(const struct connection *c)
77{
78 return ((c->flags << 4) ^ c->flags) & 0xF0000000;
79}
80
81/* Automatically updates polling on connection <c> depending on the DATA flags
82 * if no handshake is in progress.
83 */
84static inline void conn_cond_update_data_polling(struct connection *c)
85{
86 if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
87 conn_update_data_polling(c);
88}
89
90/* Automatically updates polling on connection <c> depending on the SOCK flags
91 * if a handshake is in progress.
92 */
93static inline void conn_cond_update_sock_polling(struct connection *c)
94{
95 if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
96 conn_update_sock_polling(c);
97}
98
99/* Automatically update polling on connection <c> depending on the DATA and
100 * SOCK flags, and on whether a handshake is in progress or not. This may be
101 * called at any moment when there is a doubt about the effectiveness of the
102 * polling state, for instance when entering or leaving the handshake state.
103 */
104static inline void conn_cond_update_polling(struct connection *c)
105{
106 if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
107 conn_update_data_polling(c);
108 else if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
109 conn_update_sock_polling(c);
110}
111
112/***** Event manipulation primitives for use by DATA I/O callbacks *****/
113/* The __conn_* versions do not propagate to lower layers and are only meant
114 * to be used by handlers called by the connection handler. The other ones
115 * may be used anywhere.
116 */
117static inline void __conn_data_want_recv(struct connection *c)
118{
119 c->flags |= CO_FL_DATA_RD_ENA;
120}
121
122static inline void __conn_data_stop_recv(struct connection *c)
123{
124 c->flags &= ~CO_FL_DATA_RD_ENA;
125}
126
127static inline void __conn_data_poll_recv(struct connection *c)
128{
129 c->flags |= CO_FL_DATA_RD_POL | CO_FL_DATA_RD_ENA;
130}
131
132static inline void __conn_data_want_send(struct connection *c)
133{
134 c->flags |= CO_FL_DATA_WR_ENA;
135}
136
137static inline void __conn_data_stop_send(struct connection *c)
138{
139 c->flags &= ~CO_FL_DATA_WR_ENA;
140}
141
142static inline void __conn_data_poll_send(struct connection *c)
143{
144 c->flags |= CO_FL_DATA_WR_POL | CO_FL_DATA_WR_ENA;
145}
146
147static inline void __conn_data_stop_both(struct connection *c)
148{
149 c->flags &= ~(CO_FL_DATA_WR_ENA | CO_FL_DATA_RD_ENA);
150}
151
152static inline void conn_data_want_recv(struct connection *c)
153{
154 __conn_data_want_recv(c);
155 conn_cond_update_data_polling(c);
156}
157
158static inline void conn_data_stop_recv(struct connection *c)
159{
160 __conn_data_stop_recv(c);
161 conn_cond_update_data_polling(c);
162}
163
164static inline void conn_data_poll_recv(struct connection *c)
165{
166 __conn_data_poll_recv(c);
167 conn_cond_update_data_polling(c);
168}
169
170static inline void conn_data_want_send(struct connection *c)
171{
172 __conn_data_want_send(c);
173 conn_cond_update_data_polling(c);
174}
175
176static inline void conn_data_stop_send(struct connection *c)
177{
178 __conn_data_stop_send(c);
179 conn_cond_update_data_polling(c);
180}
181
182static inline void conn_data_poll_send(struct connection *c)
183{
184 __conn_data_poll_send(c);
185 conn_cond_update_data_polling(c);
186}
187
188static inline void conn_data_stop_both(struct connection *c)
189{
190 __conn_data_stop_both(c);
191 conn_cond_update_data_polling(c);
192}
193
194/***** Event manipulation primitives for use by handshake I/O callbacks *****/
195/* The __conn_* versions do not propagate to lower layers and are only meant
196 * to be used by handlers called by the connection handler. The other ones
197 * may be used anywhere.
198 */
199static inline void __conn_sock_want_recv(struct connection *c)
200{
201 c->flags |= CO_FL_SOCK_RD_ENA;
202}
203
204static inline void __conn_sock_stop_recv(struct connection *c)
205{
206 c->flags &= ~CO_FL_SOCK_RD_ENA;
207}
208
209static inline void __conn_sock_poll_recv(struct connection *c)
210{
211 c->flags |= CO_FL_SOCK_RD_POL | CO_FL_SOCK_RD_ENA;
212}
213
214static inline void __conn_sock_want_send(struct connection *c)
215{
216 c->flags |= CO_FL_SOCK_WR_ENA;
217}
218
219static inline void __conn_sock_stop_send(struct connection *c)
220{
221 c->flags &= ~CO_FL_SOCK_WR_ENA;
222}
223
224static inline void __conn_sock_poll_send(struct connection *c)
225{
226 c->flags |= CO_FL_SOCK_WR_POL | CO_FL_SOCK_WR_ENA;
227}
228
229static inline void __conn_sock_stop_both(struct connection *c)
230{
231 c->flags &= ~(CO_FL_SOCK_WR_ENA | CO_FL_SOCK_RD_ENA);
232}
233
234static inline void conn_sock_want_recv(struct connection *c)
235{
236 __conn_sock_want_recv(c);
237 conn_cond_update_sock_polling(c);
238}
239
240static inline void conn_sock_stop_recv(struct connection *c)
241{
242 __conn_sock_stop_recv(c);
243 conn_cond_update_sock_polling(c);
244}
245
246static inline void conn_sock_poll_recv(struct connection *c)
247{
248 __conn_sock_poll_recv(c);
249 conn_cond_update_sock_polling(c);
250}
251
252static inline void conn_sock_want_send(struct connection *c)
253{
254 __conn_sock_want_send(c);
255 conn_cond_update_sock_polling(c);
256}
257
258static inline void conn_sock_stop_send(struct connection *c)
259{
260 __conn_sock_stop_send(c);
261 conn_cond_update_sock_polling(c);
262}
263
264static inline void conn_sock_poll_send(struct connection *c)
265{
266 __conn_sock_poll_send(c);
267 conn_cond_update_sock_polling(c);
268}
269
270static inline void conn_sock_stop_both(struct connection *c)
271{
272 __conn_sock_stop_both(c);
273 conn_cond_update_sock_polling(c);
274}
Willy Tarreau8b117082012-08-06 15:06:49 +0200275
Willy Tarreau3af56a92012-08-20 16:55:48 +0200276/* shutdown management */
277static inline void conn_sock_read0(struct connection *c)
278{
279 c->flags |= CO_FL_SOCK_RD_SH;
280 __conn_sock_stop_recv(c);
281}
282
283static inline void conn_data_read0(struct connection *c)
284{
285 c->flags |= CO_FL_DATA_RD_SH;
286 __conn_data_stop_recv(c);
287}
288
289static inline void conn_sock_shutw(struct connection *c)
290{
291 c->flags |= CO_FL_SOCK_WR_SH;
292 __conn_sock_stop_send(c);
293}
294
295static inline void conn_data_shutw(struct connection *c)
296{
297 c->flags |= CO_FL_DATA_WR_SH;
298 __conn_data_stop_send(c);
299}
300
301/* detect sock->data read0 transition */
302static inline int conn_data_read0_pending(struct connection *c)
303{
304 return (c->flags & (CO_FL_DATA_RD_SH | CO_FL_SOCK_RD_SH)) == CO_FL_SOCK_RD_SH;
305}
306
307/* detect data->sock shutw transition */
308static inline int conn_sock_shutw_pending(struct connection *c)
309{
310 return (c->flags & (CO_FL_DATA_WR_SH | CO_FL_SOCK_WR_SH)) == CO_FL_DATA_WR_SH;
311}
312
Willy Tarreau59f98392012-07-06 14:13:49 +0200313#endif /* _PROTO_CONNECTION_H */
314
315/*
316 * Local variables:
317 * c-indent-level: 8
318 * c-basic-offset: 8
319 * End:
320 */