blob: 32e77cf71a9a86b77a778f37d0f8850a14ac4e14 [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>
Willy Tarreaud1d54542012-09-12 22:58:11 +020027#include <types/listener.h>
Willy Tarreau59f98392012-07-06 14:13:49 +020028
29/* I/O callback for fd-based connections. It calls the read/write handlers
Willy Tarreauafad0e02012-08-09 14:45:22 +020030 * provided by the connection's sock_ops. Returns 0.
Willy Tarreau59f98392012-07-06 14:13:49 +020031 */
32int conn_fd_handler(int fd);
33
Willy Tarreau22cda212012-08-31 17:43:29 +020034/* receive a PROXY protocol header over a connection */
35int conn_recv_proxy(struct connection *conn, int flag);
36
Willy Tarreau15678ef2012-08-31 13:54:11 +020037/* calls the init() function of the data layer if any. Returns <0 in case of
38 * error.
39 */
40static inline int conn_data_init(struct connection *conn)
41{
42 if (conn->data && conn->data->init)
43 return conn->data->init(conn);
44 return 0;
45}
46
Willy Tarreau8b117082012-08-06 15:06:49 +020047/* Calls the close() function of the data layer if any */
48static inline void conn_data_close(struct connection *conn)
49{
Willy Tarreau4a36b562012-08-06 19:31:45 +020050 if (conn->data && conn->data->close)
Willy Tarreau8b117082012-08-06 15:06:49 +020051 conn->data->close(conn);
52}
53
Willy Tarreaue9dfa792012-09-01 17:26:16 +020054/* Update polling on connection <c>'s file descriptor depending on its current
55 * state as reported in the connection's CO_FL_CURR_* flags, reports of EAGAIN
56 * in CO_FL_WAIT_*, and the sock layer expectations indicated by CO_FL_SOCK_*.
57 * The connection flags are updated with the new flags at the end of the
58 * operation.
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020059 */
Willy Tarreaue9dfa792012-09-01 17:26:16 +020060void conn_update_sock_polling(struct connection *c);
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020061
Willy Tarreaue9dfa792012-09-01 17:26:16 +020062/* Update polling on connection <c>'s file descriptor depending on its current
63 * state as reported in the connection's CO_FL_CURR_* flags, reports of EAGAIN
64 * in CO_FL_WAIT_*, and the data layer expectations indicated by CO_FL_DATA_*.
65 * The connection flags are updated with the new flags at the end of the
66 * operation.
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020067 */
Willy Tarreaue9dfa792012-09-01 17:26:16 +020068void conn_update_data_polling(struct connection *c);
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020069
Willy Tarreaue9dfa792012-09-01 17:26:16 +020070/* inspects c->flags and returns non-zero if DATA ENA changes from the CURR ENA
71 * or if the WAIT flags set new flags that were not in CURR POL.
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020072 */
73static inline unsigned int conn_data_polling_changes(const struct connection *c)
74{
Willy Tarreaue9dfa792012-09-01 17:26:16 +020075 return (((c->flags << 6) ^ (c->flags << 2)) | /* changes in ENA go to bits 30&31 */
76 (((c->flags << 8) & ~c->flags))) & /* new bits in POL go to bits 30&31 */
77 0xC0000000;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020078}
79
Willy Tarreaue9dfa792012-09-01 17:26:16 +020080/* inspects c->flags and returns non-zero if SOCK ENA changes from the CURR ENA
81 * or if the WAIT flags set new flags that were not in CURR POL.
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020082 */
83static inline unsigned int conn_sock_polling_changes(const struct connection *c)
84{
Willy Tarreaue9dfa792012-09-01 17:26:16 +020085 return (((c->flags << 4) ^ (c->flags << 2)) | /* changes in ENA go to bits 30&31 */
86 (((c->flags << 8) & ~c->flags))) & /* new bits in POL go to bits 30&31 */
87 0xC0000000;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +020088}
89
90/* Automatically updates polling on connection <c> depending on the DATA flags
91 * if no handshake is in progress.
92 */
93static inline void conn_cond_update_data_polling(struct connection *c)
94{
95 if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
96 conn_update_data_polling(c);
97}
98
99/* Automatically updates polling on connection <c> depending on the SOCK flags
100 * if a handshake is in progress.
101 */
102static inline void conn_cond_update_sock_polling(struct connection *c)
103{
104 if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
105 conn_update_sock_polling(c);
106}
107
108/* Automatically update polling on connection <c> depending on the DATA and
109 * SOCK flags, and on whether a handshake is in progress or not. This may be
110 * called at any moment when there is a doubt about the effectiveness of the
111 * polling state, for instance when entering or leaving the handshake state.
112 */
113static inline void conn_cond_update_polling(struct connection *c)
114{
115 if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
116 conn_update_data_polling(c);
117 else if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
118 conn_update_sock_polling(c);
119}
120
121/***** Event manipulation primitives for use by DATA I/O callbacks *****/
122/* The __conn_* versions do not propagate to lower layers and are only meant
123 * to be used by handlers called by the connection handler. The other ones
124 * may be used anywhere.
125 */
126static inline void __conn_data_want_recv(struct connection *c)
127{
128 c->flags |= CO_FL_DATA_RD_ENA;
129}
130
131static inline void __conn_data_stop_recv(struct connection *c)
132{
133 c->flags &= ~CO_FL_DATA_RD_ENA;
134}
135
136static inline void __conn_data_poll_recv(struct connection *c)
137{
Willy Tarreaue9dfa792012-09-01 17:26:16 +0200138 c->flags |= CO_FL_WAIT_RD | CO_FL_DATA_RD_ENA;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +0200139}
140
141static inline void __conn_data_want_send(struct connection *c)
142{
143 c->flags |= CO_FL_DATA_WR_ENA;
144}
145
146static inline void __conn_data_stop_send(struct connection *c)
147{
148 c->flags &= ~CO_FL_DATA_WR_ENA;
149}
150
151static inline void __conn_data_poll_send(struct connection *c)
152{
Willy Tarreaue9dfa792012-09-01 17:26:16 +0200153 c->flags |= CO_FL_WAIT_WR | CO_FL_DATA_WR_ENA;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +0200154}
155
156static inline void __conn_data_stop_both(struct connection *c)
157{
158 c->flags &= ~(CO_FL_DATA_WR_ENA | CO_FL_DATA_RD_ENA);
159}
160
161static inline void conn_data_want_recv(struct connection *c)
162{
163 __conn_data_want_recv(c);
164 conn_cond_update_data_polling(c);
165}
166
167static inline void conn_data_stop_recv(struct connection *c)
168{
169 __conn_data_stop_recv(c);
170 conn_cond_update_data_polling(c);
171}
172
173static inline void conn_data_poll_recv(struct connection *c)
174{
175 __conn_data_poll_recv(c);
176 conn_cond_update_data_polling(c);
177}
178
179static inline void conn_data_want_send(struct connection *c)
180{
181 __conn_data_want_send(c);
182 conn_cond_update_data_polling(c);
183}
184
185static inline void conn_data_stop_send(struct connection *c)
186{
187 __conn_data_stop_send(c);
188 conn_cond_update_data_polling(c);
189}
190
191static inline void conn_data_poll_send(struct connection *c)
192{
193 __conn_data_poll_send(c);
194 conn_cond_update_data_polling(c);
195}
196
197static inline void conn_data_stop_both(struct connection *c)
198{
199 __conn_data_stop_both(c);
200 conn_cond_update_data_polling(c);
201}
202
203/***** Event manipulation primitives for use by handshake I/O callbacks *****/
204/* The __conn_* versions do not propagate to lower layers and are only meant
205 * to be used by handlers called by the connection handler. The other ones
206 * may be used anywhere.
207 */
208static inline void __conn_sock_want_recv(struct connection *c)
209{
210 c->flags |= CO_FL_SOCK_RD_ENA;
211}
212
213static inline void __conn_sock_stop_recv(struct connection *c)
214{
215 c->flags &= ~CO_FL_SOCK_RD_ENA;
216}
217
218static inline void __conn_sock_poll_recv(struct connection *c)
219{
Willy Tarreaue9dfa792012-09-01 17:26:16 +0200220 c->flags |= CO_FL_WAIT_RD | CO_FL_SOCK_RD_ENA;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +0200221}
222
223static inline void __conn_sock_want_send(struct connection *c)
224{
225 c->flags |= CO_FL_SOCK_WR_ENA;
226}
227
228static inline void __conn_sock_stop_send(struct connection *c)
229{
230 c->flags &= ~CO_FL_SOCK_WR_ENA;
231}
232
233static inline void __conn_sock_poll_send(struct connection *c)
234{
Willy Tarreaue9dfa792012-09-01 17:26:16 +0200235 c->flags |= CO_FL_WAIT_WR | CO_FL_SOCK_WR_ENA;
Willy Tarreaub5e2cbd2012-08-17 11:55:04 +0200236}
237
238static inline void __conn_sock_stop_both(struct connection *c)
239{
240 c->flags &= ~(CO_FL_SOCK_WR_ENA | CO_FL_SOCK_RD_ENA);
241}
242
243static inline void conn_sock_want_recv(struct connection *c)
244{
245 __conn_sock_want_recv(c);
246 conn_cond_update_sock_polling(c);
247}
248
249static inline void conn_sock_stop_recv(struct connection *c)
250{
251 __conn_sock_stop_recv(c);
252 conn_cond_update_sock_polling(c);
253}
254
255static inline void conn_sock_poll_recv(struct connection *c)
256{
257 __conn_sock_poll_recv(c);
258 conn_cond_update_sock_polling(c);
259}
260
261static inline void conn_sock_want_send(struct connection *c)
262{
263 __conn_sock_want_send(c);
264 conn_cond_update_sock_polling(c);
265}
266
267static inline void conn_sock_stop_send(struct connection *c)
268{
269 __conn_sock_stop_send(c);
270 conn_cond_update_sock_polling(c);
271}
272
273static inline void conn_sock_poll_send(struct connection *c)
274{
275 __conn_sock_poll_send(c);
276 conn_cond_update_sock_polling(c);
277}
278
279static inline void conn_sock_stop_both(struct connection *c)
280{
281 __conn_sock_stop_both(c);
282 conn_cond_update_sock_polling(c);
283}
Willy Tarreau8b117082012-08-06 15:06:49 +0200284
Willy Tarreau3af56a92012-08-20 16:55:48 +0200285/* shutdown management */
286static inline void conn_sock_read0(struct connection *c)
287{
288 c->flags |= CO_FL_SOCK_RD_SH;
289 __conn_sock_stop_recv(c);
290}
291
292static inline void conn_data_read0(struct connection *c)
293{
294 c->flags |= CO_FL_DATA_RD_SH;
295 __conn_data_stop_recv(c);
296}
297
298static inline void conn_sock_shutw(struct connection *c)
299{
300 c->flags |= CO_FL_SOCK_WR_SH;
301 __conn_sock_stop_send(c);
302}
303
304static inline void conn_data_shutw(struct connection *c)
305{
306 c->flags |= CO_FL_DATA_WR_SH;
307 __conn_data_stop_send(c);
308}
309
310/* detect sock->data read0 transition */
311static inline int conn_data_read0_pending(struct connection *c)
312{
313 return (c->flags & (CO_FL_DATA_RD_SH | CO_FL_SOCK_RD_SH)) == CO_FL_SOCK_RD_SH;
314}
315
316/* detect data->sock shutw transition */
317static inline int conn_sock_shutw_pending(struct connection *c)
318{
319 return (c->flags & (CO_FL_DATA_WR_SH | CO_FL_SOCK_WR_SH)) == CO_FL_DATA_WR_SH;
320}
321
Willy Tarreau3cefd522012-08-30 15:49:18 +0200322static inline void clear_target(struct target *dest)
323{
324 dest->type = TARG_TYPE_NONE;
325 dest->ptr.v = NULL;
326}
327
328static inline void set_target_client(struct target *dest, struct listener *l)
329{
330 dest->type = TARG_TYPE_CLIENT;
331 dest->ptr.l = l;
332}
333
334static inline void set_target_server(struct target *dest, struct server *s)
335{
336 dest->type = TARG_TYPE_SERVER;
337 dest->ptr.s = s;
338}
339
340static inline void set_target_proxy(struct target *dest, struct proxy *p)
341{
342 dest->type = TARG_TYPE_PROXY;
343 dest->ptr.p = p;
344}
345
346static inline void set_target_applet(struct target *dest, struct si_applet *a)
347{
348 dest->type = TARG_TYPE_APPLET;
349 dest->ptr.a = a;
350}
351
352static inline void set_target_task(struct target *dest, struct task *t)
353{
354 dest->type = TARG_TYPE_TASK;
355 dest->ptr.t = t;
356}
357
358static inline struct target *copy_target(struct target *dest, struct target *src)
359{
360 *dest = *src;
361 return dest;
362}
363
364static inline int target_match(struct target *a, struct target *b)
365{
366 return a->type == b->type && a->ptr.v == b->ptr.v;
367}
368
369static inline struct server *target_srv(struct target *t)
370{
371 if (!t || t->type != TARG_TYPE_SERVER)
372 return NULL;
373 return t->ptr.s;
374}
375
376static inline struct listener *target_client(struct target *t)
377{
378 if (!t || t->type != TARG_TYPE_CLIENT)
379 return NULL;
380 return t->ptr.l;
381}
382
Willy Tarreau986a9d22012-08-30 21:11:38 +0200383/* Retrieves the connection's source address */
384static inline void conn_get_from_addr(struct connection *conn)
385{
386 if (conn->flags & CO_FL_ADDR_FROM_SET)
387 return;
388
389 if (!conn->ctrl || !conn->ctrl->get_src)
390 return;
391
392 if (conn->ctrl->get_src(conn->t.sock.fd, (struct sockaddr *)&conn->addr.from,
393 sizeof(conn->addr.from),
394 conn->target.type != TARG_TYPE_CLIENT) == -1)
395 return;
396 conn->flags |= CO_FL_ADDR_FROM_SET;
397}
398
399/* Retrieves the connection's original destination address */
400static inline void conn_get_to_addr(struct connection *conn)
401{
402 if (conn->flags & CO_FL_ADDR_TO_SET)
403 return;
404
405 if (!conn->ctrl || !conn->ctrl->get_dst)
406 return;
407
408 if (conn->ctrl->get_dst(conn->t.sock.fd, (struct sockaddr *)&conn->addr.to,
409 sizeof(conn->addr.to),
410 conn->target.type != TARG_TYPE_CLIENT) == -1)
411 return;
412 conn->flags |= CO_FL_ADDR_TO_SET;
413}
414
415
Willy Tarreau59f98392012-07-06 14:13:49 +0200416#endif /* _PROTO_CONNECTION_H */
417
418/*
419 * Local variables:
420 * c-indent-level: 8
421 * c-basic-offset: 8
422 * End:
423 */