blob: ab0de118a9a4a95ce089ad07333303add39ffe34 [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 Tarreau54469402006-07-29 16:59:06 +020041/* Initializes all fields in the buffer. The ->rlim field is initialized last
42 * 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 Tarreau2df28e82008-08-17 15:20:19 +020051 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020052 buf->cons = NULL;
Willy Tarreaue393fe22008-08-16 22:18:07 +020053 buf->flags = BF_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020054 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaue393fe22008-08-16 22:18:07 +020055 buf->rlim = buf->data + BUFSIZE;
Willy Tarreau54469402006-07-29 16:59:06 +020056}
57
Willy Tarreaubaaee002006-06-26 02:48:02 +020058/* returns 1 if the buffer is empty, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020059static inline int buffer_isempty(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +020060{
61 return buf->l == 0;
62}
63
64/* returns 1 if the buffer is full, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020065static inline int buffer_isfull(const struct buffer *buf) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020066 return buf->l == BUFSIZE;
67}
68
Willy Tarreau2eb52f02008-09-04 09:14:08 +020069/* Check buffer timeouts, and set the corresponding flags. The
70 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010071 * The read/write timeouts are not set if there was activity on the buffer.
72 * That way, we don't have to update the timeout on every I/O. Note that the
73 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020074 */
75static inline void buffer_check_timeouts(struct buffer *b)
76{
Willy Tarreau86491c32008-12-14 09:04:47 +010077 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020078 unlikely(tick_is_expired(b->rex, now_ms)))
79 b->flags |= BF_READ_TIMEOUT;
80
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010081 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020082 unlikely(tick_is_expired(b->wex, now_ms)))
83 b->flags |= BF_WRITE_TIMEOUT;
84
85 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
86 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
87 b->flags |= BF_ANA_TIMEOUT;
88}
89
Willy Tarreaue393fe22008-08-16 22:18:07 +020090/* flushes any content from buffer <buf> and adjusts flags
91 * accordingly.
92 */
Willy Tarreaubaaee002006-06-26 02:48:02 +020093static inline void buffer_flush(struct buffer *buf)
94{
Willy Tarreauf890dc92008-12-13 21:12:26 +010095 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010096 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +010097 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +020098 buf->l = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020099 buf->flags |= BF_EMPTY | BF_FULL;
100 if (buf->rlim)
101 buf->flags &= ~BF_FULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200102}
103
Willy Tarreauba392ce2008-08-16 21:13:23 +0200104/* marks the buffer as "shutdown" for reads and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +0200105static inline void buffer_shutr(struct buffer *buf)
106{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200107 buf->rex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200108 buf->flags |= BF_SHUTR;
Willy Tarreaufa645582007-06-03 15:59:52 +0200109}
110
Willy Tarreauba392ce2008-08-16 21:13:23 +0200111/* marks the buffer as "shutdown" for writes and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +0200112static inline void buffer_shutw(struct buffer *buf)
113{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200114 buf->wex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200115 buf->flags |= BF_SHUTW;
Willy Tarreaufa645582007-06-03 15:59:52 +0200116}
117
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200118/* marks the buffer as "shutdown" ASAP for reads */
119static inline void buffer_shutr_now(struct buffer *buf)
120{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100121 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200122}
123
124/* marks the buffer as "shutdown" ASAP for writes */
125static inline void buffer_shutw_now(struct buffer *buf)
126{
127 buf->flags |= BF_SHUTW_NOW;
128}
129
130/* marks the buffer as "shutdown" ASAP in both directions */
131static inline void buffer_abort(struct buffer *buf)
132{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100133 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200134}
135
Willy Tarreau01bf8672008-12-07 18:03:29 +0100136/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
137 * flag is set, and the function called once. The function is responsible for
138 * clearing the hijack bit. It is possible that the function clears the flag
139 * during this first call.
140 */
141static inline void buffer_install_hijacker(struct session *s,
142 struct buffer *b,
143 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200144{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100145 b->hijacker = func;
146 b->flags |= BF_HIJACK;
147 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200148}
149
Willy Tarreau01bf8672008-12-07 18:03:29 +0100150/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200151static inline void buffer_stop_hijack(struct buffer *buf)
152{
153 buf->flags &= ~BF_HIJACK;
154}
155
Willy Tarreau3da77c52008-08-29 09:58:42 +0200156/* allows the consumer to send the buffer contents */
157static inline void buffer_write_ena(struct buffer *buf)
158{
159 buf->flags |= BF_WRITE_ENA;
160}
161
162/* prevents the consumer from sending the buffer contents */
163static inline void buffer_write_dis(struct buffer *buf)
164{
165 buf->flags &= ~BF_WRITE_ENA;
166}
167
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100168/* check if the buffer needs to be shut down for read, and perform the shutdown
169 * at the stream_interface level if needed. This must not be used with a buffer
170 * for which a connection is currently in queue or turn-around.
171 */
172static inline void buffer_check_shutr(struct buffer *b)
173{
174 if (b->flags & BF_SHUTR)
175 return;
176
177 if (!(b->flags & (BF_SHUTR_NOW|BF_SHUTW)))
178 return;
179
180 /* Last read, forced read-shutdown, or other end closed. We have to
181 * close our read side and inform the stream_interface.
182 */
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100183 b->prod->shutr(b->prod);
184}
185
186/* check if the buffer needs to be shut down for write, and perform the shutdown
187 * at the stream_interface level if needed. This must not be used with a buffer
188 * for which a connection is currently in queue or turn-around.
189 */
190static inline void buffer_check_shutw(struct buffer *b)
191{
192 if (b->flags & BF_SHUTW)
193 return;
194
195 if ((b->flags & BF_SHUTW_NOW) ||
196 (b->flags & (BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) ==
197 (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) {
198 /* Application requested write-shutdown, or other end closed
199 * with empty buffer. We have to close our write side and
200 * inform the stream_interface.
201 */
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100202 b->cons->shutw(b->cons);
203 }
204}
205
Willy Tarreaubaaee002006-06-26 02:48:02 +0200206/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200207static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200208{
209 if (buf->l == BUFSIZE)
210 return 0;
211 else if (buf->r >= buf->w)
212 return buf->data + BUFSIZE - buf->r;
213 else
214 return buf->w - buf->r;
215}
216
Willy Tarreaue393fe22008-08-16 22:18:07 +0200217/* sets the buffer read limit to <size> bytes, and adjusts the FULL
218 * flag accordingly.
219 */
220static inline void buffer_set_rlim(struct buffer *buf, int size)
221{
222 buf->rlim = buf->data + size;
223 if (buf->l < size)
224 buf->flags &= ~BF_FULL;
225 else
226 buf->flags |= BF_FULL;
227}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200228
229/*
230 * Tries to realign the given buffer, and returns how many bytes can be written
231 * there at once without overwriting anything.
232 */
233static inline int buffer_realign(struct buffer *buf)
234{
235 if (buf->l == 0) {
236 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100237 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200238 }
239 return buffer_max(buf);
240}
241
242
243int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100244int buffer_write_chunk(struct buffer *buf, struct chunk *chunk);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100245int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
246int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
247int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100248int chunk_printf(struct chunk *chk, int size, const char *fmt, ...);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100249void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250
Willy Tarreau0f772532006-12-23 20:51:41 +0100251/*
252 * frees the destination chunk if already allocated, allocates a new string,
253 * and copies the source into it. The pointer to the destination string is
254 * returned, or NULL if the allocation fails or if any pointer is NULL..
255 */
256static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
257 if (!dst || !src || !src->str)
258 return NULL;
259 if (dst->str)
260 free(dst->str);
261 dst->len = src->len;
262 dst->str = (char *)malloc(dst->len);
263 memcpy(dst->str, src->str, dst->len);
264 return dst->str;
265}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200266
267#endif /* _PROTO_BUFFERS_H */
268
269/*
270 * Local variables:
271 * c-indent-level: 8
272 * c-basic-offset: 8
273 * End:
274 */