include/common/defaults.h
Miscellaneous default values.
- Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
+ Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
#define MAXREWRITE (BUFSIZE / 2)
#endif
-/* FORWARD_DEFAULT_SIZE
- * Indicates how many bytes may be forwarded at once in low-level stream-socks
- * without waking the owner task up. This should be much larger than the buffer
- * size. A few megabytes seem appropriate.
- */
-#ifndef FORWARD_DEFAULT_SIZE
-#define FORWARD_DEFAULT_SIZE (16*1024*1024)
-#endif
-
-
#define REQURI_LEN 1024
#define CAPTURE_LEN 64
* cause lockups when send_max goes down to zero if nobody is ready to push the
* remaining data.
*/
-static inline void buffer_forward(struct buffer *buf, unsigned int bytes)
+static inline void buffer_forward(struct buffer *buf, unsigned long bytes)
{
- unsigned int data_left;
+ unsigned long data_left;
if (!bytes)
return;
return;
}
- buf->to_forward += bytes - data_left;
buf->send_max += data_left;
+ if (buf->to_forward == BUF_INFINITE_FORWARD)
+ return;
+
+ buf->to_forward += bytes - data_left;
+ if (bytes == BUF_INFINITE_FORWARD)
+ buf->to_forward = bytes;
}
/* Schedule all remaining buffer data to be sent. send_max is not touched if it
if (buf->r - buf->data == buf->size)
buf->r -= buf->size;
- if ((signed)(buf->to_forward - 1) >= 0) {
- buf->to_forward--;
+ if (buf->to_forward >= 1) {
+ if (buf->to_forward != BUF_INFINITE_FORWARD)
+ buf->to_forward--;
buf->send_max++;
buf->flags &= ~BF_OUT_EMPTY;
}
#define AN_RTR_HTTP_HDR 0x00000200 /* inspect HTTP response headers */
#define AN_REQ_PRST_RDP_COOKIE 0x00000400 /* persistence on rdp cookie */
+/* Magic value to forward infinite size (TCP, ...), used with ->to_forward */
+#define BUF_INFINITE_FORWARD (~0UL)
+
/* describes a chunk of string */
struct chunk {
char *str; /* beginning of the string itself. Might not be 0-terminated */
unsigned int size; /* buffer size in bytes */
unsigned int max_len; /* read limit, used to keep room for header rewriting */
unsigned int send_max; /* number of bytes the sender can consume om this buffer, <= l */
- unsigned int to_forward; /* number of bytes to forward after send_max without a wake-up */
+ unsigned long to_forward; /* number of bytes to forward after send_max without a wake-up */
unsigned int analysers; /* bit field indicating what to do on the buffer */
int analyse_exp; /* expiration date for current analysers (if set) */
void (*hijacker)(struct session *, struct buffer *); /* alternative content producer */
The producer is responsible for decreasing ->to_forward and increasing
->send_max. The ->to_forward parameter indicates how many bytes may be fed
- into either data buffer without waking the parent up. The ->send_max
+ into either data buffer without waking the parent up. The special value
+ BUF_INFINITE_FORWARD is never decreased nor increased. The ->send_max
parameter says how many bytes may be read from the visible buffer. Thus it
may never exceed ->l. This parameter is updated by any buffer_write() as
well as any data forwarded through the visible buffer.
buf->l += len;
buf->r += len;
buf->total += len;
- if (buf->to_forward > 0) {
- int fwd = MIN(buf->to_forward, len);
- buf->send_max += fwd;
- buf->to_forward -= fwd;
+ if (buf->to_forward) {
+ unsigned long fwd = len;
+ if (buf->to_forward != BUF_INFINITE_FORWARD) {
+ if (fwd > buf->to_forward)
+ fwd = buf->to_forward;
+ buf->to_forward -= fwd;
+ }
+ buf->send_max += fwd;
buf->flags &= ~BF_OUT_EMPTY;
}
/* If noone is interested in analysing data, it's time to forward
- * everything. We will wake up from time to time when either send_max
- * or to_forward are reached.
+ * everything. We configure the buffer to forward indefinitely.
*/
if (!s->req->analysers &&
!(s->req->flags & (BF_HIJACK|BF_SHUTW)) &&
- (s->req->prod->state >= SI_ST_EST)) {
+ (s->req->prod->state >= SI_ST_EST) &&
+ (s->req->to_forward != BUF_INFINITE_FORWARD)) {
/* This buffer is freewheeling, there's no analyser nor hijacker
* attached to it. If any data are left in, we'll permit them to
* move.
buffer_auto_close(s->req);
buffer_flush(s->req);
- /* If the producer is still connected, we'll schedule large blocks
- * of data to be forwarded from the producer to the consumer (which
- * might possibly not be connected yet).
+ /* If the producer is still connected, we'll enable data to flow
+ * from the producer to the consumer (which might possibly not be
+ * connected yet).
*/
- if (!(s->req->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)) &&
- s->req->to_forward < FORWARD_DEFAULT_SIZE)
- buffer_forward(s->req, FORWARD_DEFAULT_SIZE);
+ if (!(s->req->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)))
+ buffer_forward(s->req, BUF_INFINITE_FORWARD);
}
/* check if it is wise to enable kernel splicing to forward request data */
/* perform output updates to the response buffer */
/* If noone is interested in analysing data, it's time to forward
- * everything. We will wake up from time to time when either send_max
- * or to_forward are reached.
+ * everything. We configure the buffer to forward indefinitely.
*/
if (!s->rep->analysers &&
!(s->rep->flags & (BF_HIJACK|BF_SHUTW)) &&
- (s->rep->prod->state >= SI_ST_EST)) {
+ (s->rep->prod->state >= SI_ST_EST) &&
+ (s->rep->to_forward != BUF_INFINITE_FORWARD)) {
/* This buffer is freewheeling, there's no analyser nor hijacker
* attached to it. If any data are left in, we'll permit them to
* move.
*/
buffer_auto_close(s->rep);
buffer_flush(s->rep);
-
- /* If the producer is still connected, we'll schedule large blocks
- * of data to be forwarded from the producer to the consumer (which
- * might possibly not be connected yet).
- */
- if (!(s->rep->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)) &&
- s->rep->to_forward < FORWARD_DEFAULT_SIZE)
- buffer_forward(s->rep, FORWARD_DEFAULT_SIZE);
+ if (!(s->rep->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)))
+ buffer_forward(s->rep, BUF_INFINITE_FORWARD);
}
/* check if it is wise to enable kernel splicing to forward response data */
static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
{
int fd = si->fd;
- int ret, max, total = 0;
+ int ret;
+ unsigned long max;
int retval = 1;
if (!b->to_forward)
while (1) {
max = b->to_forward;
- if (max <= 0) {
+ if (!max) {
/* It looks like the buffer + the pipe already contain
* the maximum amount of data to be transferred. Try to
* send those data immediately on the other side if it
break;
} /* ret <= 0 */
- b->to_forward -= ret;
- total += ret;
+ if (b->to_forward != BUF_INFINITE_FORWARD)
+ b->to_forward -= ret;
b->total += ret;
b->pipe->data += ret;
b->flags |= BF_READ_PARTIAL;
cur_read += ret;
/* if we're allowed to directly forward data, we must update send_max */
- if (b->to_forward > 0 && !(b->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
- int fwd = MIN(b->to_forward, ret);
- b->send_max += fwd;
- b->to_forward -= fwd;
+ if (b->to_forward && !(b->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
+ unsigned long fwd = ret;
+ if (b->to_forward != BUF_INFINITE_FORWARD) {
+ if (fwd > b->to_forward)
+ fwd = b->to_forward;
+ b->to_forward -= fwd;
+ }
+ b->send_max += fwd;
b->flags &= ~BF_OUT_EMPTY;
}