blob: 1597b0fc5dba731fd3cee942c67fa4c37c9cad45 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
Willy Tarreauc7e42382012-08-24 19:22:53 +02002 * Channel management functions.
Willy Tarreaubaaee002006-06-26 02:48:02 +02003 *
Willy Tarreauc7e42382012-08-24 19:22:53 +02004 * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +020013#include <ctype.h>
Willy Tarreauc0dde7a2007-01-01 21:38:07 +010014#include <stdarg.h>
15#include <stdio.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020016#include <string.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020017
18#include <common/config.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020019#include <common/memory.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020020#include <common/buffer.h>
21#include <proto/channel.h>
Willy Tarreau27a674e2009-08-17 07:23:33 +020022#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020023
Willy Tarreauc7e42382012-08-24 19:22:53 +020024
25/* Note: this code has not yet been completely cleaned up and still refers to
26 * the word "buffer" when "channel" is meant instead.
27 */
Willy Tarreau7341d942007-05-13 19:56:02 +020028struct pool_head *pool2_buffer;
29
30
31/* perform minimal intializations, report 0 in case of error, 1 if OK. */
32int init_buffer()
33{
Willy Tarreau7421efb2012-07-02 15:11:27 +020034 pool2_buffer = create_pool("buffer", sizeof(struct channel) + global.tune.bufsize, MEM_F_SHARED);
Willy Tarreau7341d942007-05-13 19:56:02 +020035 return pool2_buffer != NULL;
36}
37
Willy Tarreau0bc34932011-03-28 16:25:58 +020038/* Schedule up to <bytes> more bytes to be forwarded by the buffer without notifying
39 * the task. Any pending data in the buffer is scheduled to be sent as well,
40 * in the limit of the number of bytes to forward. This must be the only method
41 * to use to schedule bytes to be sent. If the requested number is too large, it
42 * is automatically adjusted. The number of bytes taken into account is returned.
Willy Tarreau2e046c62012-03-01 16:08:30 +010043 * Directly touching ->to_forward will cause lockups when ->o goes down to
Willy Tarreau0bc34932011-03-28 16:25:58 +020044 * zero if nobody is ready to push the remaining data.
45 */
Willy Tarreau7421efb2012-07-02 15:11:27 +020046unsigned long long buffer_forward(struct channel *buf, unsigned long long bytes)
Willy Tarreau0bc34932011-03-28 16:25:58 +020047{
Willy Tarreau0bc34932011-03-28 16:25:58 +020048 unsigned int new_forward;
Willy Tarreau02d6cfc2012-03-01 18:19:58 +010049 unsigned int forwarded;
Willy Tarreau328582c2012-05-05 23:32:27 +020050 unsigned int bytes32;
Willy Tarreau0bc34932011-03-28 16:25:58 +020051
Willy Tarreau328582c2012-05-05 23:32:27 +020052 bytes32 = bytes;
53
54 /* hint: avoid comparisons on long long for the fast case, since if the
55 * length does not fit in an unsigned it, it will never be forwarded at
56 * once anyway.
57 */
58 if (bytes <= ~0U) {
Willy Tarreau572bf902012-07-02 17:01:20 +020059 if (bytes32 <= buf->buf.i) {
Willy Tarreau328582c2012-05-05 23:32:27 +020060 /* OK this amount of bytes might be forwarded at once */
61 if (!bytes32)
62 return 0;
Willy Tarreaua75bcef2012-08-24 22:56:11 +020063 b_adv(&buf->buf, bytes32);
Willy Tarreau328582c2012-05-05 23:32:27 +020064 return bytes;
65 }
Willy Tarreau0bc34932011-03-28 16:25:58 +020066 }
67
Willy Tarreau572bf902012-07-02 17:01:20 +020068 forwarded = buf->buf.i;
Willy Tarreaua75bcef2012-08-24 22:56:11 +020069 b_adv(&buf->buf, buf->buf.i);
Willy Tarreau0bc34932011-03-28 16:25:58 +020070
Willy Tarreau0bc34932011-03-28 16:25:58 +020071 /* Note: the case below is the only case where we may return
72 * a byte count that does not fit into a 32-bit number.
73 */
Willy Tarreau03cdb7c2012-08-27 23:14:58 +020074 if (likely(buf->to_forward == CHN_INFINITE_FORWARD))
Willy Tarreau0bc34932011-03-28 16:25:58 +020075 return bytes;
76
Willy Tarreau03cdb7c2012-08-27 23:14:58 +020077 if (likely(bytes == CHN_INFINITE_FORWARD)) {
Willy Tarreau02d6cfc2012-03-01 18:19:58 +010078 buf->to_forward = bytes;
79 return bytes;
80 }
81
82 new_forward = buf->to_forward + bytes - forwarded;
83 bytes = forwarded; /* at least those bytes were scheduled */
Willy Tarreau0bc34932011-03-28 16:25:58 +020084
85 if (new_forward <= buf->to_forward) {
86 /* integer overflow detected, let's assume no more than 2G at once */
87 new_forward = MID_RANGE(new_forward);
88 }
89
90 if (new_forward > buf->to_forward) {
91 bytes += new_forward - buf->to_forward;
92 buf->to_forward = new_forward;
93 }
94 return bytes;
95}
Willy Tarreaubaaee002006-06-26 02:48:02 +020096
Krzysztof Piotr Oledzki8e4b21d2008-04-20 21:34:47 +020097/* writes <len> bytes from message <msg> to buffer <buf>. Returns -1 in case of
Willy Tarreau078e2942009-08-18 07:19:39 +020098 * success, -2 if the message is larger than the buffer size, or the number of
99 * bytes available otherwise. The send limit is automatically adjusted with the
100 * amount of data written. FIXME-20060521: handle unaligned data.
Willy Tarreau363a5bb2012-03-02 20:14:45 +0100101 * Note: this function appends data to the buffer's output and possibly overwrites
102 * any pending input data which are assumed not to exist.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200103 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200104int bo_inject(struct channel *buf, const char *msg, int len)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200105{
106 int max;
107
Willy Tarreauaeac3192009-08-31 08:09:57 +0200108 if (len == 0)
109 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200110
Willy Tarreau572bf902012-07-02 17:01:20 +0200111 if (len > buf->buf.size) {
Willy Tarreau078e2942009-08-18 07:19:39 +0200112 /* we can't write this chunk and will never be able to, because
113 * it is larger than the buffer. This must be reported as an
114 * error. Then we return -2 so that writers that don't care can
115 * ignore it and go on, and others can check for this value.
116 */
117 return -2;
118 }
119
Willy Tarreau572bf902012-07-02 17:01:20 +0200120 max = buffer_realign(&buf->buf);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200121
Willy Tarreaubaaee002006-06-26 02:48:02 +0200122 if (len > max)
123 return max;
124
Willy Tarreau572bf902012-07-02 17:01:20 +0200125 memcpy(buf->buf.p, msg, len);
126 buf->buf.o += len;
127 buf->buf.p = b_ptr(&buf->buf, len);
Willy Tarreau35d66b02007-01-02 00:28:21 +0100128 buf->total += len;
Krzysztof Piotr Oledzki8e4b21d2008-04-20 21:34:47 +0200129 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200130}
131
Willy Tarreau74b08c92010-09-08 17:04:31 +0200132/* Tries to copy character <c> into buffer <buf> after length controls. The
Willy Tarreau2e046c62012-03-01 16:08:30 +0100133 * ->o and to_forward pointers are updated. If the buffer's input is
Willy Tarreau74b08c92010-09-08 17:04:31 +0200134 * closed, -2 is returned. If there is not enough room left in the buffer, -1
135 * is returned. Otherwise the number of bytes copied is returned (1). Buffer
Willy Tarreauf941cf22012-08-27 20:53:34 +0200136 * flag READ_PARTIAL is updated if some data can be transferred.
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100137 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200138int bi_putchr(struct channel *buf, char c)
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100139{
Willy Tarreau74b08c92010-09-08 17:04:31 +0200140 if (unlikely(buffer_input_closed(buf)))
141 return -2;
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100142
Willy Tarreau3bf1b2b2012-08-27 20:46:07 +0200143 if (channel_full(buf))
Krzysztof Piotr Oledzki8e4b21d2008-04-20 21:34:47 +0200144 return -1;
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100145
Willy Tarreau572bf902012-07-02 17:01:20 +0200146 *bi_end(&buf->buf) = c;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200147
Willy Tarreau572bf902012-07-02 17:01:20 +0200148 buf->buf.i++;
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200149 buf->flags |= CF_READ_PARTIAL;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200150
Willy Tarreau74b08c92010-09-08 17:04:31 +0200151 if (buf->to_forward >= 1) {
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200152 if (buf->to_forward != CHN_INFINITE_FORWARD)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200153 buf->to_forward--;
Willy Tarreaua75bcef2012-08-24 22:56:11 +0200154 b_adv(&buf->buf, 1);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200155 }
156
157 buf->total++;
158 return 1;
159}
160
161/* Tries to copy block <blk> at once into buffer <buf> after length controls.
Willy Tarreau2e046c62012-03-01 16:08:30 +0100162 * The ->o and to_forward pointers are updated. If the buffer's input is
Willy Tarreau74b08c92010-09-08 17:04:31 +0200163 * closed, -2 is returned. If the block is too large for this buffer, -3 is
164 * returned. If there is not enough room left in the buffer, -1 is returned.
165 * Otherwise the number of bytes copied is returned (0 being a valid number).
Willy Tarreauf941cf22012-08-27 20:53:34 +0200166 * Buffer flag READ_PARTIAL is updated if some data can be transferred.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200167 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200168int bi_putblk(struct channel *buf, const char *blk, int len)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200169{
170 int max;
171
172 if (unlikely(buffer_input_closed(buf)))
173 return -2;
174
Willy Tarreau591fedc2010-08-10 15:28:21 +0200175 max = buffer_max_len(buf);
Willy Tarreau572bf902012-07-02 17:01:20 +0200176 if (unlikely(len > max - buffer_len(&buf->buf))) {
Willy Tarreau591fedc2010-08-10 15:28:21 +0200177 /* we can't write this chunk right now because the buffer is
178 * almost full or because the block is too large. Return the
179 * available space or -2 if impossible.
Willy Tarreau078e2942009-08-18 07:19:39 +0200180 */
Willy Tarreau591fedc2010-08-10 15:28:21 +0200181 if (len > max)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200182 return -3;
Willy Tarreau078e2942009-08-18 07:19:39 +0200183
Willy Tarreau74b08c92010-09-08 17:04:31 +0200184 return -1;
Willy Tarreau591fedc2010-08-10 15:28:21 +0200185 }
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100186
Willy Tarreau74b08c92010-09-08 17:04:31 +0200187 if (unlikely(len == 0))
188 return 0;
189
Willy Tarreau591fedc2010-08-10 15:28:21 +0200190 /* OK so the data fits in the buffer in one or two blocks */
Willy Tarreau572bf902012-07-02 17:01:20 +0200191 max = buffer_contig_space_with_res(&buf->buf, buf->buf.size - max);
192 memcpy(bi_end(&buf->buf), blk, MIN(len, max));
Willy Tarreauaeac3192009-08-31 08:09:57 +0200193 if (len > max)
Willy Tarreau572bf902012-07-02 17:01:20 +0200194 memcpy(buf->buf.data, blk + max, len - max);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100195
Willy Tarreau572bf902012-07-02 17:01:20 +0200196 buf->buf.i += len;
Willy Tarreauaeac3192009-08-31 08:09:57 +0200197 buf->total += len;
Willy Tarreau31971e52009-09-20 12:07:52 +0200198 if (buf->to_forward) {
199 unsigned long fwd = len;
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200200 if (buf->to_forward != CHN_INFINITE_FORWARD) {
Willy Tarreau31971e52009-09-20 12:07:52 +0200201 if (fwd > buf->to_forward)
202 fwd = buf->to_forward;
203 buf->to_forward -= fwd;
204 }
Willy Tarreaua75bcef2012-08-24 22:56:11 +0200205 b_adv(&buf->buf, fwd);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200206 }
207
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200208 /* notify that some data was read from the SI into the buffer */
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200209 buf->flags |= CF_READ_PARTIAL;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200210 return len;
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100211}
212
Willy Tarreau74b08c92010-09-08 17:04:31 +0200213/* Gets one text line out of a buffer from a stream interface.
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200214 * Return values :
215 * >0 : number of bytes read. Includes the \n if present before len or end.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200216 * =0 : no '\n' before end found. <str> is left undefined.
217 * <0 : no more bytes readable because output is shut.
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200218 * The buffer status is not changed. The caller must call bo_skip() to
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200219 * update it. The '\n' is waited for as long as neither the buffer nor the
220 * output are full. If either of them is full, the string may be returned
221 * as is, without the '\n'.
222 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200223int bo_getline(struct channel *buf, char *str, int len)
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200224{
225 int ret, max;
226 char *p;
227
228 ret = 0;
229 max = len;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200230
231 /* closed or empty + imminent close = -1; empty = 0 */
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200232 if (unlikely((buf->flags & CF_SHUTW) || channel_is_empty(buf))) {
233 if (buf->flags & (CF_SHUTW|CF_SHUTW_NOW))
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200234 ret = -1;
235 goto out;
236 }
237
Willy Tarreau572bf902012-07-02 17:01:20 +0200238 p = bo_ptr(&buf->buf);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200239
Willy Tarreau572bf902012-07-02 17:01:20 +0200240 if (max > buf->buf.o) {
241 max = buf->buf.o;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200242 str[max-1] = 0;
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200243 }
244 while (max) {
245 *str++ = *p;
246 ret++;
247 max--;
248
249 if (*p == '\n')
250 break;
Willy Tarreau572bf902012-07-02 17:01:20 +0200251 p = buffer_wrap_add(&buf->buf, p + 1);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200252 }
Willy Tarreau572bf902012-07-02 17:01:20 +0200253 if (ret > 0 && ret < len && ret < buf->buf.o &&
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200254 *(str-1) != '\n' &&
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200255 !(buf->flags & (CF_SHUTW|CF_SHUTW_NOW)))
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200256 ret = 0;
257 out:
258 if (max)
259 *str = 0;
260 return ret;
261}
262
Willy Tarreau74b08c92010-09-08 17:04:31 +0200263/* Gets one full block of data at once from a buffer, optionally from a
264 * specific offset. Return values :
265 * >0 : number of bytes read, equal to requested size.
266 * =0 : not enough data available. <blk> is left undefined.
267 * <0 : no more bytes readable because output is shut.
Willy Tarreau9dab5fc2012-05-07 11:56:55 +0200268 * The buffer status is not changed. The caller must call bo_skip() to
Willy Tarreau74b08c92010-09-08 17:04:31 +0200269 * update it.
270 */
Willy Tarreau7421efb2012-07-02 15:11:27 +0200271int bo_getblk(struct channel *buf, char *blk, int len, int offset)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200272{
273 int firstblock;
274
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200275 if (buf->flags & CF_SHUTW)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200276 return -1;
277
Willy Tarreau572bf902012-07-02 17:01:20 +0200278 if (len + offset > buf->buf.o) {
Willy Tarreau03cdb7c2012-08-27 23:14:58 +0200279 if (buf->flags & (CF_SHUTW|CF_SHUTW_NOW))
Willy Tarreau74b08c92010-09-08 17:04:31 +0200280 return -1;
281 return 0;
282 }
283
Willy Tarreau572bf902012-07-02 17:01:20 +0200284 firstblock = buf->buf.data + buf->buf.size - bo_ptr(&buf->buf);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200285 if (firstblock > offset) {
286 if (firstblock >= len + offset) {
Willy Tarreau572bf902012-07-02 17:01:20 +0200287 memcpy(blk, bo_ptr(&buf->buf) + offset, len);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200288 return len;
289 }
290
Willy Tarreau572bf902012-07-02 17:01:20 +0200291 memcpy(blk, bo_ptr(&buf->buf) + offset, firstblock - offset);
292 memcpy(blk + firstblock - offset, buf->buf.data, len - firstblock + offset);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200293 return len;
294 }
295
Willy Tarreau572bf902012-07-02 17:01:20 +0200296 memcpy(blk, buf->buf.data + offset - firstblock, len);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200297 return len;
298}
299
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200300/*
Willy Tarreaubaaee002006-06-26 02:48:02 +0200301 * Local variables:
302 * c-indent-level: 8
303 * c-basic-offset: 8
304 * End:
305 */