blob: 6b5771b6ab6263f6435c4825fb58453fc3a1b629 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 include/proto/buffers.h
3 Buffer management definitions, macros and inline functions.
4
Willy Tarreauba392ce2008-08-16 21:13:23 +02005 Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +01006
Willy Tarreaubaaee002006-06-26 02:48:02 +02007 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_BUFFERS_H
23#define _PROTO_BUFFERS_H
24
Willy Tarreau7341d942007-05-13 19:56:02 +020025#include <stdio.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010026#include <stdlib.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020027#include <string.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010028
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020029#include <common/config.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020030#include <common/memory.h>
Willy Tarreau0c303ee2008-07-07 00:09:58 +020031#include <common/ticks.h>
Willy Tarreaufa645582007-06-03 15:59:52 +020032#include <common/time.h>
33
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <types/buffers.h>
35
Willy Tarreau7341d942007-05-13 19:56:02 +020036extern struct pool_head *pool2_buffer;
37
38/* perform minimal intializations, report 0 in case of error, 1 if OK. */
39int init_buffer();
40
Willy Tarreau03d60bb2009-01-09 11:13:00 +010041/* Initializes all fields in the buffer. The ->max_len field is initialized last
Willy Tarreau54469402006-07-29 16:59:06 +020042 * so that the compiler can optimize it away if changed immediately after the
Willy Tarreaue393fe22008-08-16 22:18:07 +020043 * call to this function. By default, it is set to the full size of the buffer.
44 * The BF_EMPTY flags is set.
Willy Tarreau54469402006-07-29 16:59:06 +020045 */
46static inline void buffer_init(struct buffer *buf)
47{
Willy Tarreauf890dc92008-12-13 21:12:26 +010048 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010049 buf->to_forward = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020050 buf->l = buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010051 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020052 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020053 buf->cons = NULL;
Willy Tarreaue393fe22008-08-16 22:18:07 +020054 buf->flags = BF_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020055 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreau03d60bb2009-01-09 11:13:00 +010056 buf->max_len = BUFSIZE;
Willy Tarreau54469402006-07-29 16:59:06 +020057}
58
Willy Tarreaubaaee002006-06-26 02:48:02 +020059/* returns 1 if the buffer is empty, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020060static inline int buffer_isempty(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +020061{
62 return buf->l == 0;
63}
64
65/* returns 1 if the buffer is full, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020066static inline int buffer_isfull(const struct buffer *buf) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020067 return buf->l == BUFSIZE;
68}
69
Willy Tarreau2eb52f02008-09-04 09:14:08 +020070/* Check buffer timeouts, and set the corresponding flags. The
71 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010072 * The read/write timeouts are not set if there was activity on the buffer.
73 * That way, we don't have to update the timeout on every I/O. Note that the
74 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020075 */
76static inline void buffer_check_timeouts(struct buffer *b)
77{
Willy Tarreau86491c32008-12-14 09:04:47 +010078 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020079 unlikely(tick_is_expired(b->rex, now_ms)))
80 b->flags |= BF_READ_TIMEOUT;
81
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010082 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020083 unlikely(tick_is_expired(b->wex, now_ms)))
84 b->flags |= BF_WRITE_TIMEOUT;
85
86 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
87 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
88 b->flags |= BF_ANA_TIMEOUT;
89}
90
Willy Tarreau0abebcc2009-01-08 00:09:41 +010091/* Schedule <bytes> more bytes to be forwarded by the buffer without notifying
92 * the task. Any pending data in the buffer is scheduled to be sent as well,
93 * in the limit of the number of bytes to forward. This must be the only method
94 * to use to schedule bytes to be sent. Directly touching ->to_forward will
95 * cause lockups when send_max goes down to zero if nobody is ready to push the
96 * remaining data.
97 */
98static inline void buffer_forward(struct buffer *buf, unsigned int bytes)
99{
100 unsigned int data_left;
101
102 buf->to_forward += bytes;
103 data_left = buf->l - buf->send_max;
104 if (data_left > buf->to_forward)
105 data_left = buf->to_forward;
106
107 buf->to_forward -= data_left;
108 buf->send_max += data_left;
109}
110
111/* Flush any content from buffer <buf> and adjusts flags accordingly. Note
112 * that any spliced data is not affected since we may not have any access to
113 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200114 */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200115static inline void buffer_flush(struct buffer *buf)
116{
Willy Tarreauf890dc92008-12-13 21:12:26 +0100117 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100118 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100119 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200120 buf->l = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +0200121 buf->flags |= BF_EMPTY | BF_FULL;
Willy Tarreau03d60bb2009-01-09 11:13:00 +0100122 if (buf->max_len)
Willy Tarreaue393fe22008-08-16 22:18:07 +0200123 buf->flags &= ~BF_FULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200124}
125
Willy Tarreauba392ce2008-08-16 21:13:23 +0200126/* marks the buffer as "shutdown" for reads and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +0200127static inline void buffer_shutr(struct buffer *buf)
128{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200129 buf->rex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200130 buf->flags |= BF_SHUTR;
Willy Tarreaufa645582007-06-03 15:59:52 +0200131}
132
Willy Tarreauba392ce2008-08-16 21:13:23 +0200133/* marks the buffer as "shutdown" for writes and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +0200134static inline void buffer_shutw(struct buffer *buf)
135{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200136 buf->wex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200137 buf->flags |= BF_SHUTW;
Willy Tarreaufa645582007-06-03 15:59:52 +0200138}
139
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200140/* marks the buffer as "shutdown" ASAP for reads */
141static inline void buffer_shutr_now(struct buffer *buf)
142{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100143 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200144}
145
146/* marks the buffer as "shutdown" ASAP for writes */
147static inline void buffer_shutw_now(struct buffer *buf)
148{
149 buf->flags |= BF_SHUTW_NOW;
150}
151
152/* marks the buffer as "shutdown" ASAP in both directions */
153static inline void buffer_abort(struct buffer *buf)
154{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100155 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200156}
157
Willy Tarreau01bf8672008-12-07 18:03:29 +0100158/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
159 * flag is set, and the function called once. The function is responsible for
160 * clearing the hijack bit. It is possible that the function clears the flag
161 * during this first call.
162 */
163static inline void buffer_install_hijacker(struct session *s,
164 struct buffer *b,
165 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200166{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100167 b->hijacker = func;
168 b->flags |= BF_HIJACK;
169 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200170}
171
Willy Tarreau01bf8672008-12-07 18:03:29 +0100172/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200173static inline void buffer_stop_hijack(struct buffer *buf)
174{
175 buf->flags &= ~BF_HIJACK;
176}
177
Willy Tarreau3da77c52008-08-29 09:58:42 +0200178/* allows the consumer to send the buffer contents */
179static inline void buffer_write_ena(struct buffer *buf)
180{
181 buf->flags |= BF_WRITE_ENA;
182}
183
184/* prevents the consumer from sending the buffer contents */
185static inline void buffer_write_dis(struct buffer *buf)
186{
187 buf->flags &= ~BF_WRITE_ENA;
188}
189
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100190/* check if the buffer needs to be shut down for read, and perform the shutdown
191 * at the stream_interface level if needed. This must not be used with a buffer
192 * for which a connection is currently in queue or turn-around.
193 */
194static inline void buffer_check_shutr(struct buffer *b)
195{
196 if (b->flags & BF_SHUTR)
197 return;
198
199 if (!(b->flags & (BF_SHUTR_NOW|BF_SHUTW)))
200 return;
201
202 /* Last read, forced read-shutdown, or other end closed. We have to
203 * close our read side and inform the stream_interface.
204 */
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100205 b->prod->shutr(b->prod);
206}
207
208/* check if the buffer needs to be shut down for write, and perform the shutdown
209 * at the stream_interface level if needed. This must not be used with a buffer
210 * for which a connection is currently in queue or turn-around.
211 */
212static inline void buffer_check_shutw(struct buffer *b)
213{
214 if (b->flags & BF_SHUTW)
215 return;
216
217 if ((b->flags & BF_SHUTW_NOW) ||
218 (b->flags & (BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) ==
219 (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) {
220 /* Application requested write-shutdown, or other end closed
221 * with empty buffer. We have to close our write side and
222 * inform the stream_interface.
223 */
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100224 b->cons->shutw(b->cons);
225 }
226}
227
Willy Tarreaubaaee002006-06-26 02:48:02 +0200228/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200229static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200230{
231 if (buf->l == BUFSIZE)
232 return 0;
233 else if (buf->r >= buf->w)
234 return buf->data + BUFSIZE - buf->r;
235 else
236 return buf->w - buf->r;
237}
238
Willy Tarreaue393fe22008-08-16 22:18:07 +0200239/* sets the buffer read limit to <size> bytes, and adjusts the FULL
240 * flag accordingly.
241 */
242static inline void buffer_set_rlim(struct buffer *buf, int size)
243{
Willy Tarreau03d60bb2009-01-09 11:13:00 +0100244 buf->max_len = size;
Willy Tarreaue393fe22008-08-16 22:18:07 +0200245 if (buf->l < size)
246 buf->flags &= ~BF_FULL;
247 else
248 buf->flags |= BF_FULL;
249}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250
251/*
252 * Tries to realign the given buffer, and returns how many bytes can be written
253 * there at once without overwriting anything.
254 */
255static inline int buffer_realign(struct buffer *buf)
256{
257 if (buf->l == 0) {
258 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100259 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200260 }
261 return buffer_max(buf);
262}
263
264
265int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100266int buffer_write_chunk(struct buffer *buf, struct chunk *chunk);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100267int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
268int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
269int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100270int chunk_printf(struct chunk *chk, int size, const char *fmt, ...);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100271void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200272
Willy Tarreau0f772532006-12-23 20:51:41 +0100273/*
274 * frees the destination chunk if already allocated, allocates a new string,
275 * and copies the source into it. The pointer to the destination string is
276 * returned, or NULL if the allocation fails or if any pointer is NULL..
277 */
278static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
279 if (!dst || !src || !src->str)
280 return NULL;
281 if (dst->str)
282 free(dst->str);
283 dst->len = src->len;
284 dst->str = (char *)malloc(dst->len);
285 memcpy(dst->str, src->str, dst->len);
286 return dst->str;
287}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200288
289#endif /* _PROTO_BUFFERS_H */
290
291/*
292 * Local variables:
293 * c-indent-level: 8
294 * c-basic-offset: 8
295 * End:
296 */