blob: 57428d20ba1fd65a34a17cb8a58e0ac7db956812 [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>
Willy Tarreaubaaee002006-06-26 02:48:02 +020021
Willy Tarreau9b28e032012-10-12 23:49:43 +020022#include <proto/channel.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020023
Willy Tarreau8263d2b2012-08-28 00:06:31 +020024struct pool_head *pool2_channel;
Willy Tarreau7341d942007-05-13 19:56:02 +020025
26
27/* perform minimal intializations, report 0 in case of error, 1 if OK. */
Willy Tarreau8263d2b2012-08-28 00:06:31 +020028int init_channel()
Willy Tarreau7341d942007-05-13 19:56:02 +020029{
Willy Tarreau9b28e032012-10-12 23:49:43 +020030 pool2_channel = create_pool("channel", sizeof(struct channel), MEM_F_SHARED);
Willy Tarreau8263d2b2012-08-28 00:06:31 +020031 return pool2_channel != NULL;
Willy Tarreau7341d942007-05-13 19:56:02 +020032}
33
Willy Tarreau8263d2b2012-08-28 00:06:31 +020034/* Schedule up to <bytes> more bytes to be forwarded via the channel without
35 * notifying the owner task. Any data pending in the buffer are scheduled to be
Willy Tarreau74602122016-05-04 14:05:58 +020036 * sent as well, within the limit of the number of bytes to forward. This must
37 * be the only method to use to schedule bytes to be forwarded. If the requested
Willy Tarreau8263d2b2012-08-28 00:06:31 +020038 * number is too large, it is automatically adjusted. The number of bytes taken
39 * into account is returned. Directly touching ->to_forward will cause lockups
40 * when buf->o goes down to zero if nobody is ready to push the remaining data.
Willy Tarreau0bc34932011-03-28 16:25:58 +020041 */
Willy Tarreau55a69062012-10-26 00:21:52 +020042unsigned long long __channel_forward(struct channel *chn, unsigned long long bytes)
Willy Tarreau0bc34932011-03-28 16:25:58 +020043{
Willy Tarreau74602122016-05-04 14:05:58 +020044 unsigned int budget;
Willy Tarreau02d6cfc2012-03-01 18:19:58 +010045 unsigned int forwarded;
Willy Tarreau0bc34932011-03-28 16:25:58 +020046
Willy Tarreau74602122016-05-04 14:05:58 +020047 /* This is more of a safety measure as it's not supposed to happen in
48 * regular code paths.
Willy Tarreau0bc34932011-03-28 16:25:58 +020049 */
Willy Tarreau74602122016-05-04 14:05:58 +020050 if (unlikely(chn->to_forward == CHN_INFINITE_FORWARD)) {
51 b_adv(chn->buf, chn->buf->i);
Willy Tarreau02d6cfc2012-03-01 18:19:58 +010052 return bytes;
53 }
54
Willy Tarreau74602122016-05-04 14:05:58 +020055 /* Bound the transferred size to a 32-bit count since all our values
56 * are 32-bit, and we don't want to reach CHN_INFINITE_FORWARD.
57 */
58 budget = MIN(bytes, CHN_INFINITE_FORWARD - 1);
Willy Tarreau0bc34932011-03-28 16:25:58 +020059
Willy Tarreau74602122016-05-04 14:05:58 +020060 /* transfer as much as we can of buf->i */
61 forwarded = MIN(chn->buf->i, budget);
62 b_adv(chn->buf, forwarded);
63 budget -= forwarded;
Willy Tarreau0bc34932011-03-28 16:25:58 +020064
Willy Tarreau74602122016-05-04 14:05:58 +020065 if (!budget)
66 return forwarded;
67
68 /* Now we must ensure chn->to_forward sats below CHN_INFINITE_FORWARD,
69 * which also implies it won't overflow. It's less operations in 64-bit.
70 */
71 bytes = (unsigned long long)chn->to_forward + budget;
72 if (bytes >= CHN_INFINITE_FORWARD)
73 bytes = CHN_INFINITE_FORWARD - 1;
74 budget = bytes - chn->to_forward;
75
76 chn->to_forward += budget;
77 forwarded += budget;
78 return forwarded;
Willy Tarreau0bc34932011-03-28 16:25:58 +020079}
Willy Tarreaubaaee002006-06-26 02:48:02 +020080
Willy Tarreau8263d2b2012-08-28 00:06:31 +020081/* writes <len> bytes from message <msg> to the channel's buffer. Returns -1 in
82 * case of success, -2 if the message is larger than the buffer size, or the
83 * number of bytes available otherwise. The send limit is automatically
84 * adjusted to the amount of data written. FIXME-20060521: handle unaligned
85 * data. Note: this function appends data to the buffer's output and possibly
86 * overwrites any pending input data which are assumed not to exist.
Willy Tarreaubaaee002006-06-26 02:48:02 +020087 */
Willy Tarreau974ced62012-10-12 23:11:02 +020088int bo_inject(struct channel *chn, const char *msg, int len)
Willy Tarreaubaaee002006-06-26 02:48:02 +020089{
90 int max;
91
Willy Tarreauaeac3192009-08-31 08:09:57 +020092 if (len == 0)
93 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020094
Willy Tarreauce0162e2016-02-25 16:15:19 +010095 if (len < 0 || len > chn->buf->size) {
Willy Tarreau078e2942009-08-18 07:19:39 +020096 /* we can't write this chunk and will never be able to, because
97 * it is larger than the buffer. This must be reported as an
98 * error. Then we return -2 so that writers that don't care can
99 * ignore it and go on, and others can check for this value.
100 */
101 return -2;
102 }
103
Willy Tarreau9b28e032012-10-12 23:49:43 +0200104 max = buffer_realign(chn->buf);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200105
Willy Tarreaubaaee002006-06-26 02:48:02 +0200106 if (len > max)
107 return max;
108
Willy Tarreau9b28e032012-10-12 23:49:43 +0200109 memcpy(chn->buf->p, msg, len);
110 chn->buf->o += len;
111 chn->buf->p = b_ptr(chn->buf, len);
Willy Tarreau974ced62012-10-12 23:11:02 +0200112 chn->total += len;
Krzysztof Piotr Oledzki8e4b21d2008-04-20 21:34:47 +0200113 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200114}
115
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200116/* Tries to copy character <c> into the channel's buffer after some length
Willy Tarreau974ced62012-10-12 23:11:02 +0200117 * controls. The chn->o and to_forward pointers are updated. If the channel
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200118 * input is closed, -2 is returned. If there is not enough room left in the
119 * buffer, -1 is returned. Otherwise the number of bytes copied is returned
120 * (1). Channel flag READ_PARTIAL is updated if some data can be transferred.
Willy Tarreaud7ad9f52013-12-31 17:26:25 +0100121 * Channel flag CF_WAKE_WRITE is set if the write fails because the buffer is
122 * full.
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100123 */
Willy Tarreau974ced62012-10-12 23:11:02 +0200124int bi_putchr(struct channel *chn, char c)
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100125{
Willy Tarreau974ced62012-10-12 23:11:02 +0200126 if (unlikely(channel_input_closed(chn)))
Willy Tarreau74b08c92010-09-08 17:04:31 +0200127 return -2;
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100128
Willy Tarreaud7ad9f52013-12-31 17:26:25 +0100129 if (channel_full(chn)) {
130 chn->flags |= CF_WAKE_WRITE;
Krzysztof Piotr Oledzki8e4b21d2008-04-20 21:34:47 +0200131 return -1;
Willy Tarreaud7ad9f52013-12-31 17:26:25 +0100132 }
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100133
Willy Tarreau9b28e032012-10-12 23:49:43 +0200134 *bi_end(chn->buf) = c;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200135
Willy Tarreau9b28e032012-10-12 23:49:43 +0200136 chn->buf->i++;
Willy Tarreau974ced62012-10-12 23:11:02 +0200137 chn->flags |= CF_READ_PARTIAL;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200138
Willy Tarreau974ced62012-10-12 23:11:02 +0200139 if (chn->to_forward >= 1) {
140 if (chn->to_forward != CHN_INFINITE_FORWARD)
141 chn->to_forward--;
Willy Tarreau9b28e032012-10-12 23:49:43 +0200142 b_adv(chn->buf, 1);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200143 }
144
Willy Tarreau974ced62012-10-12 23:11:02 +0200145 chn->total++;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200146 return 1;
147}
148
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200149/* Tries to copy block <blk> at once into the channel's buffer after length
Willy Tarreau974ced62012-10-12 23:11:02 +0200150 * controls. The chn->o and to_forward pointers are updated. If the channel
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200151 * input is closed, -2 is returned. If the block is too large for this buffer,
152 * -3 is returned. If there is not enough room left in the buffer, -1 is
153 * returned. Otherwise the number of bytes copied is returned (0 being a valid
154 * number). Channel flag READ_PARTIAL is updated if some data can be
Willy Tarreaud7ad9f52013-12-31 17:26:25 +0100155 * transferred. Channel flag CF_WAKE_WRITE is set if the write fails because
156 * the buffer is full.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200157 */
Willy Tarreau974ced62012-10-12 23:11:02 +0200158int bi_putblk(struct channel *chn, const char *blk, int len)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200159{
160 int max;
161
Willy Tarreau974ced62012-10-12 23:11:02 +0200162 if (unlikely(channel_input_closed(chn)))
Willy Tarreau74b08c92010-09-08 17:04:31 +0200163 return -2;
164
Willy Tarreauce0162e2016-02-25 16:15:19 +0100165 if (len < 0)
166 return -3;
167
Willy Tarreau974ced62012-10-12 23:11:02 +0200168 max = buffer_max_len(chn);
Willy Tarreau9b28e032012-10-12 23:49:43 +0200169 if (unlikely(len > max - buffer_len(chn->buf))) {
Willy Tarreau591fedc2010-08-10 15:28:21 +0200170 /* we can't write this chunk right now because the buffer is
171 * almost full or because the block is too large. Return the
172 * available space or -2 if impossible.
Willy Tarreau078e2942009-08-18 07:19:39 +0200173 */
Willy Tarreau591fedc2010-08-10 15:28:21 +0200174 if (len > max)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200175 return -3;
Willy Tarreau078e2942009-08-18 07:19:39 +0200176
Willy Tarreaud7ad9f52013-12-31 17:26:25 +0100177 chn->flags |= CF_WAKE_WRITE;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200178 return -1;
Willy Tarreau591fedc2010-08-10 15:28:21 +0200179 }
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100180
Willy Tarreau74b08c92010-09-08 17:04:31 +0200181 if (unlikely(len == 0))
182 return 0;
183
Willy Tarreau591fedc2010-08-10 15:28:21 +0200184 /* OK so the data fits in the buffer in one or two blocks */
Willy Tarreau285ff0f2014-04-24 17:02:57 +0200185 max = buffer_contig_space(chn->buf);
Willy Tarreau9b28e032012-10-12 23:49:43 +0200186 memcpy(bi_end(chn->buf), blk, MIN(len, max));
Willy Tarreauaeac3192009-08-31 08:09:57 +0200187 if (len > max)
Willy Tarreau9b28e032012-10-12 23:49:43 +0200188 memcpy(chn->buf->data, blk + max, len - max);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100189
Willy Tarreau9b28e032012-10-12 23:49:43 +0200190 chn->buf->i += len;
Willy Tarreau974ced62012-10-12 23:11:02 +0200191 chn->total += len;
192 if (chn->to_forward) {
Willy Tarreau31971e52009-09-20 12:07:52 +0200193 unsigned long fwd = len;
Willy Tarreau974ced62012-10-12 23:11:02 +0200194 if (chn->to_forward != CHN_INFINITE_FORWARD) {
195 if (fwd > chn->to_forward)
196 fwd = chn->to_forward;
197 chn->to_forward -= fwd;
Willy Tarreau31971e52009-09-20 12:07:52 +0200198 }
Willy Tarreau9b28e032012-10-12 23:49:43 +0200199 b_adv(chn->buf, fwd);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200200 }
201
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200202 /* notify that some data was read from the SI into the buffer */
Willy Tarreau974ced62012-10-12 23:11:02 +0200203 chn->flags |= CF_READ_PARTIAL;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200204 return len;
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100205}
206
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200207/* Gets one text line out of a channel's buffer from a stream interface.
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200208 * Return values :
209 * >0 : number of bytes read. Includes the \n if present before len or end.
Willy Tarreau74b08c92010-09-08 17:04:31 +0200210 * =0 : no '\n' before end found. <str> is left undefined.
211 * <0 : no more bytes readable because output is shut.
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200212 * The channel status is not changed. The caller must call bo_skip() to
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200213 * update it. The '\n' is waited for as long as neither the buffer nor the
214 * output are full. If either of them is full, the string may be returned
215 * as is, without the '\n'.
216 */
Willy Tarreau974ced62012-10-12 23:11:02 +0200217int bo_getline(struct channel *chn, char *str, int len)
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200218{
219 int ret, max;
220 char *p;
221
222 ret = 0;
223 max = len;
Willy Tarreau74b08c92010-09-08 17:04:31 +0200224
225 /* closed or empty + imminent close = -1; empty = 0 */
Willy Tarreau974ced62012-10-12 23:11:02 +0200226 if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
227 if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200228 ret = -1;
229 goto out;
230 }
231
Willy Tarreau9b28e032012-10-12 23:49:43 +0200232 p = bo_ptr(chn->buf);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200233
Willy Tarreau9b28e032012-10-12 23:49:43 +0200234 if (max > chn->buf->o) {
235 max = chn->buf->o;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200236 str[max-1] = 0;
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200237 }
238 while (max) {
239 *str++ = *p;
240 ret++;
241 max--;
242
243 if (*p == '\n')
244 break;
Willy Tarreau9b28e032012-10-12 23:49:43 +0200245 p = buffer_wrap_add(chn->buf, p + 1);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200246 }
Willy Tarreau82de2b62013-12-10 18:58:23 +0100247 if (ret > 0 && ret < len &&
248 (ret < chn->buf->o || !channel_full(chn)) &&
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200249 *(str-1) != '\n' &&
Willy Tarreau974ced62012-10-12 23:11:02 +0200250 !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200251 ret = 0;
252 out:
253 if (max)
254 *str = 0;
255 return ret;
256}
257
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200258/* Gets one full block of data at once from a channel's buffer, optionally from
259 * a specific offset. Return values :
Willy Tarreau74b08c92010-09-08 17:04:31 +0200260 * >0 : number of bytes read, equal to requested size.
261 * =0 : not enough data available. <blk> is left undefined.
262 * <0 : no more bytes readable because output is shut.
Willy Tarreau8263d2b2012-08-28 00:06:31 +0200263 * The channel status is not changed. The caller must call bo_skip() to
Willy Tarreau74b08c92010-09-08 17:04:31 +0200264 * update it.
265 */
Willy Tarreau974ced62012-10-12 23:11:02 +0200266int bo_getblk(struct channel *chn, char *blk, int len, int offset)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200267{
268 int firstblock;
269
Willy Tarreau974ced62012-10-12 23:11:02 +0200270 if (chn->flags & CF_SHUTW)
Willy Tarreau74b08c92010-09-08 17:04:31 +0200271 return -1;
272
Willy Tarreau9b28e032012-10-12 23:49:43 +0200273 if (len + offset > chn->buf->o) {
Willy Tarreau974ced62012-10-12 23:11:02 +0200274 if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
Willy Tarreau74b08c92010-09-08 17:04:31 +0200275 return -1;
276 return 0;
277 }
278
Willy Tarreau9b28e032012-10-12 23:49:43 +0200279 firstblock = chn->buf->data + chn->buf->size - bo_ptr(chn->buf);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200280 if (firstblock > offset) {
281 if (firstblock >= len + offset) {
Willy Tarreau9b28e032012-10-12 23:49:43 +0200282 memcpy(blk, bo_ptr(chn->buf) + offset, len);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200283 return len;
284 }
285
Willy Tarreau9b28e032012-10-12 23:49:43 +0200286 memcpy(blk, bo_ptr(chn->buf) + offset, firstblock - offset);
287 memcpy(blk + firstblock - offset, chn->buf->data, len - firstblock + offset);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200288 return len;
289 }
290
Willy Tarreau9b28e032012-10-12 23:49:43 +0200291 memcpy(blk, chn->buf->data + offset - firstblock, len);
Willy Tarreau74b08c92010-09-08 17:04:31 +0200292 return len;
293}
294
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200295/*
Willy Tarreaubaaee002006-06-26 02:48:02 +0200296 * Local variables:
297 * c-indent-level: 8
298 * c-basic-offset: 8
299 * End:
300 */