blob: c6ab71816f1b74f6e590de58df34e9ac366b9d15 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
Willy Tarreauc7e42382012-08-24 19:22:53 +02002 * include/proto/channel.h
3 * Channel management definitions, macros and inline functions.
Willy Tarreau7c3c5412009-12-13 15:53:05 +01004 *
Willy Tarreau9dab5fc2012-05-07 11:56:55 +02005 * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
Willy Tarreau7c3c5412009-12-13 15:53:05 +01006 *
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 */
Willy Tarreaubaaee002006-06-26 02:48:02 +020021
Willy Tarreauc7e42382012-08-24 19:22:53 +020022#ifndef _PROTO_CHANNEL_H
23#define _PROTO_CHANNEL_H
Willy Tarreaubaaee002006-06-26 02:48:02 +020024
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 Tarreauc7e42382012-08-24 19:22:53 +020030#include <common/chunk.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020031#include <common/memory.h>
Willy Tarreau0c303ee2008-07-07 00:09:58 +020032#include <common/ticks.h>
Willy Tarreaufa645582007-06-03 15:59:52 +020033#include <common/time.h>
34
Willy Tarreau7c3c5412009-12-13 15:53:05 +010035#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020036
Willy Tarreau7341d942007-05-13 19:56:02 +020037extern struct pool_head *pool2_buffer;
38
39/* perform minimal intializations, report 0 in case of error, 1 if OK. */
40int init_buffer();
41
Willy Tarreau74b08c92010-09-08 17:04:31 +020042/* SI-to-buffer functions : buffer_{get,put}_{char,block,string,chunk} */
Willy Tarreau7421efb2012-07-02 15:11:27 +020043int bo_inject(struct channel *buf, const char *msg, int len);
44int bi_putblk(struct channel *buf, const char *str, int len);
45int bi_putchr(struct channel *buf, char c);
46int bo_getline(struct channel *buf, char *str, int len);
47int bo_getblk(struct channel *buf, char *blk, int len, int offset);
Willy Tarreau7421efb2012-07-02 15:11:27 +020048unsigned long long buffer_forward(struct channel *buf, unsigned long long bytes);
Willy Tarreau74b08c92010-09-08 17:04:31 +020049
Willy Tarreau8e21bb92012-08-24 22:40:29 +020050/* Initialize all fields in the buffer. */
Willy Tarreau7421efb2012-07-02 15:11:27 +020051static inline void buffer_init(struct channel *buf)
Willy Tarreau54469402006-07-29 16:59:06 +020052{
Willy Tarreau572bf902012-07-02 17:01:20 +020053 buf->buf.o = 0;
54 buf->buf.i = 0;
55 buf->buf.p = buf->buf.data;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010056 buf->to_forward = 0;
Willy Tarreau02d6cfc2012-03-01 18:19:58 +010057 buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010058 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020059 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020060 buf->cons = NULL;
Willy Tarreau8e21bb92012-08-24 22:40:29 +020061 buf->flags = 0;
Willy Tarreau54469402006-07-29 16:59:06 +020062}
63
Willy Tarreau4b517ca2011-11-25 20:33:58 +010064/*****************************************************************/
65/* These functions are used to compute various buffer area sizes */
66/*****************************************************************/
67
Willy Tarreau8e21bb92012-08-24 22:40:29 +020068/* Reports non-zero if the channel is empty, which means both its
69 * buffer and pipe are empty. The construct looks strange but is
70 * jump-less and much more efficient on both 32 and 64-bit than
71 * the boolean test.
72 */
73static inline unsigned int channel_is_empty(struct channel *c)
74{
75 return !(c->buf.o | (long)c->pipe);
76}
77
Willy Tarreau4b517ca2011-11-25 20:33:58 +010078/* Return the number of reserved bytes in the buffer, which ensures that once
79 * all pending data are forwarded, the buffer still has global.tune.maxrewrite
80 * bytes free. The result is between 0 and global.maxrewrite, which is itself
81 * smaller than any buf->size.
82 */
Willy Tarreau7421efb2012-07-02 15:11:27 +020083static inline int buffer_reserved(const struct channel *buf)
Willy Tarreau4b517ca2011-11-25 20:33:58 +010084{
Willy Tarreau572bf902012-07-02 17:01:20 +020085 int ret = global.tune.maxrewrite - buf->to_forward - buf->buf.o;
Willy Tarreau4b517ca2011-11-25 20:33:58 +010086
Willy Tarreau03cdb7c2012-08-27 23:14:58 +020087 if (buf->to_forward == CHN_INFINITE_FORWARD)
Willy Tarreau4b517ca2011-11-25 20:33:58 +010088 return 0;
89 if (ret <= 0)
90 return 0;
91 return ret;
92}
93
Willy Tarreau7c3c5412009-12-13 15:53:05 +010094/* Return the max number of bytes the buffer can contain so that once all the
95 * pending bytes are forwarded, the buffer still has global.tune.maxrewrite
96 * bytes free. The result sits between buf->size - maxrewrite and buf->size.
97 */
Willy Tarreau7421efb2012-07-02 15:11:27 +020098static inline int buffer_max_len(const struct channel *buf)
Willy Tarreau4b517ca2011-11-25 20:33:58 +010099{
Willy Tarreau572bf902012-07-02 17:01:20 +0200100 return buf->buf.size - buffer_reserved(buf);
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100101}
102
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200103/* Returns non-zero if the buffer input is considered full. The reserved space
104 * is taken into account if ->to_forward indicates that an end of transfer is
105 * close to happen. The test is optimized to avoid as many operations as
106 * possible for the fast case and to be used as an "if" condition.
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100107 */
Willy Tarreauad1cc3d2012-08-27 18:54:20 +0200108static inline int channel_full(const struct channel *b)
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100109{
Willy Tarreau572bf902012-07-02 17:01:20 +0200110 int rem = b->buf.size;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200111
Willy Tarreau572bf902012-07-02 17:01:20 +0200112 rem -= b->buf.o;
113 rem -= b->buf.i;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200114 if (!rem)
115 return 1; /* buffer already full */
116
Willy Tarreau572bf902012-07-02 17:01:20 +0200117 if (b->to_forward >= b->buf.size ||
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200118 (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(b->buf.size)) && // just there to ensure gcc
119 b->to_forward == CHN_INFINITE_FORWARD)) // avoids the useless second
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200120 return 0; // test whenever possible
121
122 rem -= global.tune.maxrewrite;
Willy Tarreau572bf902012-07-02 17:01:20 +0200123 rem += b->buf.o;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200124 rem += b->to_forward;
125 return rem <= 0;
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100126}
127
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200128/* Returns the amount of space available at the input of the buffer, taking the
129 * reserved space into account if ->to_forward indicates that an end of transfer
130 * is close to happen. The test is optimized to avoid as many operations as
131 * possible for the fast case.
132 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200133static inline int bi_avail(const struct channel *b)
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200134{
Willy Tarreau572bf902012-07-02 17:01:20 +0200135 int rem = b->buf.size;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200136 int rem2;
137
Willy Tarreau572bf902012-07-02 17:01:20 +0200138 rem -= b->buf.o;
139 rem -= b->buf.i;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200140 if (!rem)
141 return rem; /* buffer already full */
142
Willy Tarreau572bf902012-07-02 17:01:20 +0200143 if (b->to_forward >= b->buf.size ||
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200144 (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(b->buf.size)) && // just there to ensure gcc
145 b->to_forward == CHN_INFINITE_FORWARD)) // avoids the useless second
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200146 return rem; // test whenever possible
147
148 rem2 = rem - global.tune.maxrewrite;
Willy Tarreau572bf902012-07-02 17:01:20 +0200149 rem2 += b->buf.o;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200150 rem2 += b->to_forward;
151
152 if (rem > rem2)
153 rem = rem2;
154 if (rem > 0)
155 return rem;
156 return 0;
157}
158
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100159/* Return the amount of bytes that can be written into the buffer at once,
Willy Tarreau363a5bb2012-03-02 20:14:45 +0100160 * excluding reserved space, which is preserved.
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100161 */
Willy Tarreau572bf902012-07-02 17:01:20 +0200162static inline int buffer_contig_space_res(const struct channel *chn)
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100163{
Willy Tarreau572bf902012-07-02 17:01:20 +0200164 return buffer_contig_space_with_res(&chn->buf, buffer_reserved(chn));
Willy Tarreau4b517ca2011-11-25 20:33:58 +0100165}
166
Willy Tarreau74b08c92010-09-08 17:04:31 +0200167/* Returns true if the buffer's input is already closed */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200168static inline int buffer_input_closed(struct channel *buf)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200169{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200170 return ((buf->flags & CF_SHUTR) != 0);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200171}
172
173/* Returns true if the buffer's output is already closed */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200174static inline int buffer_output_closed(struct channel *buf)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200175{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200176 return ((buf->flags & CF_SHUTW) != 0);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200177}
178
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200179/* Check buffer timeouts, and set the corresponding flags. The
180 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +0100181 * The read/write timeouts are not set if there was activity on the buffer.
182 * That way, we don't have to update the timeout on every I/O. Note that the
183 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200184 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200185static inline void buffer_check_timeouts(struct channel *b)
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200186{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200187 if (likely(!(b->flags & (CF_SHUTR|CF_READ_TIMEOUT|CF_READ_ACTIVITY|CF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200188 unlikely(tick_is_expired(b->rex, now_ms)))
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200189 b->flags |= CF_READ_TIMEOUT;
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200190
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200191 if (likely(!(b->flags & (CF_SHUTW|CF_WRITE_TIMEOUT|CF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200192 unlikely(tick_is_expired(b->wex, now_ms)))
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200193 b->flags |= CF_WRITE_TIMEOUT;
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200194
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200195 if (likely(!(b->flags & CF_ANA_TIMEOUT)) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200196 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200197 b->flags |= CF_ANA_TIMEOUT;
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200198}
199
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100200/* Erase any content from buffer <buf> and adjusts flags accordingly. Note
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100201 * that any spliced data is not affected since we may not have any access to
202 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200203 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200204static inline void buffer_erase(struct channel *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200205{
Willy Tarreau572bf902012-07-02 17:01:20 +0200206 buf->buf.o = 0;
207 buf->buf.i = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100208 buf->to_forward = 0;
Willy Tarreau572bf902012-07-02 17:01:20 +0200209 buf->buf.p = buf->buf.data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200210}
211
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200212/* Cut the "tail" of the buffer, which means strip it to the length of unsent
213 * data only, and kill any remaining unsent data. Any scheduled forwarding is
214 * stopped. This is mainly to be used to send error messages after existing
215 * data.
216 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200217static inline void bi_erase(struct channel *buf)
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200218{
Willy Tarreau572bf902012-07-02 17:01:20 +0200219 if (!buf->buf.o)
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200220 return buffer_erase(buf);
221
222 buf->to_forward = 0;
Willy Tarreau572bf902012-07-02 17:01:20 +0200223 if (!buf->buf.i)
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200224 return;
225
Willy Tarreau572bf902012-07-02 17:01:20 +0200226 buf->buf.i = 0;
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200227}
228
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200229/* marks the buffer as "shutdown" ASAP for reads */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200230static inline void buffer_shutr_now(struct channel *buf)
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200231{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200232 buf->flags |= CF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200233}
234
235/* marks the buffer as "shutdown" ASAP for writes */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200236static inline void buffer_shutw_now(struct channel *buf)
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200237{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200238 buf->flags |= CF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200239}
240
241/* marks the buffer as "shutdown" ASAP in both directions */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200242static inline void buffer_abort(struct channel *buf)
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200243{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200244 buf->flags |= CF_SHUTR_NOW | CF_SHUTW_NOW;
245 buf->flags &= ~CF_AUTO_CONNECT;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200246}
247
Willy Tarreau01bf8672008-12-07 18:03:29 +0100248/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
249 * flag is set, and the function called once. The function is responsible for
250 * clearing the hijack bit. It is possible that the function clears the flag
251 * during this first call.
252 */
253static inline void buffer_install_hijacker(struct session *s,
Willy Tarreau7421efb2012-07-02 15:11:27 +0200254 struct channel *b,
255 void (*func)(struct session *, struct channel *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200256{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100257 b->hijacker = func;
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200258 b->flags |= CF_HIJACK;
Willy Tarreau01bf8672008-12-07 18:03:29 +0100259 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200260}
261
Willy Tarreau01bf8672008-12-07 18:03:29 +0100262/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200263static inline void buffer_stop_hijack(struct channel *buf)
Willy Tarreau72b179a2008-08-28 16:01:32 +0200264{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200265 buf->flags &= ~CF_HIJACK;
Willy Tarreau72b179a2008-08-28 16:01:32 +0200266}
267
Willy Tarreau520d95e2009-09-19 21:04:57 +0200268/* allow the consumer to try to establish a new connection. */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200269static inline void buffer_auto_connect(struct channel *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200270{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200271 buf->flags |= CF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200272}
273
Willy Tarreau520d95e2009-09-19 21:04:57 +0200274/* prevent the consumer from trying to establish a new connection, and also
275 * disable auto shutdown forwarding.
276 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200277static inline void buffer_dont_connect(struct channel *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200278{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200279 buf->flags &= ~(CF_AUTO_CONNECT|CF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200280}
281
Willy Tarreau520d95e2009-09-19 21:04:57 +0200282/* allow the producer to forward shutdown requests */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200283static inline void buffer_auto_close(struct channel *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100284{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200285 buf->flags |= CF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100286}
287
Willy Tarreau520d95e2009-09-19 21:04:57 +0200288/* prevent the producer from forwarding shutdown requests */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200289static inline void buffer_dont_close(struct channel *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100290{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200291 buf->flags &= ~CF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100292}
293
Willy Tarreau90deb182010-01-07 00:20:41 +0100294/* allow the producer to read / poll the input */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200295static inline void buffer_auto_read(struct channel *buf)
Willy Tarreau90deb182010-01-07 00:20:41 +0100296{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200297 buf->flags &= ~CF_DONT_READ;
Willy Tarreau90deb182010-01-07 00:20:41 +0100298}
299
300/* prevent the producer from read / poll the input */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200301static inline void buffer_dont_read(struct channel *buf)
Willy Tarreau90deb182010-01-07 00:20:41 +0100302{
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200303 buf->flags |= CF_DONT_READ;
Willy Tarreau90deb182010-01-07 00:20:41 +0100304}
305
Willy Tarreaubaaee002006-06-26 02:48:02 +0200306/*
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200307 * Advance the buffer's read pointer by <len> bytes. This is useful when data
308 * have been read directly from the buffer. It is illegal to call this function
309 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e046c62012-03-01 16:08:30 +0100310 * responsibility to ensure that <len> is never larger than buf->o.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200311 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200312static inline void bo_skip(struct channel *buf, int len)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200313{
Willy Tarreau572bf902012-07-02 17:01:20 +0200314 buf->buf.o -= len;
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200315
Willy Tarreau572bf902012-07-02 17:01:20 +0200316 if (buffer_len(&buf->buf) == 0)
317 buf->buf.p = buf->buf.data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200318
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200319 /* notify that some data was written to the SI from the buffer */
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200320 buf->flags |= CF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200321}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200322
Willy Tarreau74b08c92010-09-08 17:04:31 +0200323/* Tries to copy chunk <chunk> into buffer <buf> after length controls.
Willy Tarreau2e046c62012-03-01 16:08:30 +0100324 * The ->o and to_forward pointers are updated. If the buffer's input is
Willy Tarreau74b08c92010-09-08 17:04:31 +0200325 * closed, -2 is returned. If the block is too large for this buffer, -3 is
326 * returned. If there is not enough room left in the buffer, -1 is returned.
327 * Otherwise the number of bytes copied is returned (0 being a valid number).
Willy Tarreauf941cf22012-08-27 20:53:34 +0200328 * Buffer flag READ_PARTIAL is updated if some data can be transferred. The
329 * chunk's length is updated with the number of bytes sent.
Willy Tarreauaeac3192009-08-31 08:09:57 +0200330 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200331static inline int bi_putchk(struct channel *buf, struct chunk *chunk)
Willy Tarreauaeac3192009-08-31 08:09:57 +0200332{
333 int ret;
334
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200335 ret = bi_putblk(buf, chunk->str, chunk->len);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200336 if (ret > 0)
337 chunk->len -= ret;
Willy Tarreauaeac3192009-08-31 08:09:57 +0200338 return ret;
339}
340
Willy Tarreau74b08c92010-09-08 17:04:31 +0200341/* Tries to copy string <str> at once into buffer <buf> after length controls.
Willy Tarreau2e046c62012-03-01 16:08:30 +0100342 * The ->o and to_forward pointers are updated. If the buffer's input is
Willy Tarreau74b08c92010-09-08 17:04:31 +0200343 * closed, -2 is returned. If the block is too large for this buffer, -3 is
344 * returned. If there is not enough room left in the buffer, -1 is returned.
345 * Otherwise the number of bytes copied is returned (0 being a valid number).
Willy Tarreauf941cf22012-08-27 20:53:34 +0200346 * Buffer flag READ_PARTIAL is updated if some data can be transferred.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200347 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200348static inline int bi_putstr(struct channel *buf, const char *str)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200349{
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200350 return bi_putblk(buf, str, strlen(str));
Willy Tarreau74b08c92010-09-08 17:04:31 +0200351}
352
353/*
354 * Return one char from the buffer. If the buffer is empty and closed, return -2.
355 * If the buffer is just empty, return -1. The buffer's pointer is not advanced,
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200356 * it's up to the caller to call bo_skip(buf, 1) when it has consumed the char.
Willy Tarreau2e046c62012-03-01 16:08:30 +0100357 * Also note that this function respects the ->o limit.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200358 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200359static inline int bo_getchr(struct channel *buf)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200360{
361 /* closed or empty + imminent close = -2; empty = -1 */
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200362 if (unlikely((buf->flags & CF_SHUTW) || channel_is_empty(buf))) {
363 if (buf->flags & (CF_SHUTW|CF_SHUTW_NOW))
Willy Tarreau74b08c92010-09-08 17:04:31 +0200364 return -2;
365 return -1;
366 }
Willy Tarreau572bf902012-07-02 17:01:20 +0200367 return *buffer_wrap_sub(&buf->buf, buf->buf.p - buf->buf.o);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200368}
369
Willy Tarreaubaaee002006-06-26 02:48:02 +0200370
Willy Tarreauc7e42382012-08-24 19:22:53 +0200371#endif /* _PROTO_CHANNEL_H */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200372
373/*
374 * Local variables:
375 * c-indent-level: 8
376 * c-basic-offset: 8
377 * End:
378 */