diff --git a/include/proto/buffers.h b/include/proto/buffers.h index dc9961a2b..53fd41ffc 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -41,6 +41,7 @@ int init_buffer(); /* Initializes all fields in the buffer. The ->max_len field is initialized last * so that the compiler can optimize it away if changed immediately after the * call to this function. By default, it is set to the full size of the buffer. + * This implies that buffer_init() must only be called once ->size is set ! * The BF_EMPTY flags is set. */ static inline void buffer_init(struct buffer *buf) @@ -53,7 +54,7 @@ static inline void buffer_init(struct buffer *buf) buf->cons = NULL; buf->flags = BF_EMPTY; buf->r = buf->lr = buf->w = buf->data; - buf->max_len = BUFSIZE; + buf->max_len = buf->size; } /* returns 1 if the buffer is empty, 0 otherwise */ @@ -64,7 +65,7 @@ static inline int buffer_isempty(const struct buffer *buf) /* returns 1 if the buffer is full, 0 otherwise */ static inline int buffer_isfull(const struct buffer *buf) { - return buf->l == BUFSIZE; + return buf->l == buf->size; } /* Check buffer timeouts, and set the corresponding flags. The @@ -238,10 +239,10 @@ static inline void buffer_check_shutw(struct buffer *b) /* returns the maximum number of bytes writable at once in this buffer */ static inline int buffer_max(const struct buffer *buf) { - if (buf->l == BUFSIZE) + if (buf->l == buf->size) return 0; else if (buf->r >= buf->w) - return buf->data + BUFSIZE - buf->r; + return buf->data + buf->size - buf->r; else return buf->w - buf->r; } diff --git a/include/types/buffers.h b/include/types/buffers.h index b9836b23e..84929485e 100644 --- a/include/types/buffers.h +++ b/include/types/buffers.h @@ -2,7 +2,7 @@ include/types/buffers.h Buffer management definitions, macros and inline functions. - 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 @@ -136,6 +136,7 @@ struct buffer { int cto; /* connect timeout, in ticks */ unsigned int l; /* data length */ char *r, *w, *lr; /* read ptr, write ptr, last read */ + 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 */ @@ -148,7 +149,7 @@ struct buffer { struct stream_interface *prod; /* producer attached to this buffer */ struct stream_interface *cons; /* consumer attached to this buffer */ struct pipe *pipe; /* non-NULL only when data present */ - char data[BUFSIZE]; + char data[0]; /* bytes */ }; diff --git a/src/buffers.c b/src/buffers.c index c8681cfb8..55b79639b 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -24,7 +24,7 @@ struct pool_head *pool2_buffer; /* perform minimal intializations, report 0 in case of error, 1 if OK. */ int init_buffer() { - pool2_buffer = create_pool("buffer", sizeof(struct buffer), MEM_F_SHARED); + pool2_buffer = create_pool("buffer", sizeof(struct buffer) + BUFSIZE, MEM_F_SHARED); return pool2_buffer != NULL; } @@ -48,7 +48,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len) buf->send_max += len; buf->r += len; buf->total += len; - if (buf->r == buf->data + BUFSIZE) + if (buf->r == buf->data + buf->size) buf->r = buf->data; buf->flags &= ~(BF_EMPTY|BF_FULL); @@ -82,7 +82,7 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk) buf->send_max += chunk->len; buf->r += chunk->len; buf->total += chunk->len; - if (buf->r == buf->data + BUFSIZE) + if (buf->r == buf->data + buf->size) buf->r = buf->data; buf->flags &= ~(BF_EMPTY|BF_FULL); @@ -111,7 +111,7 @@ int buffer_replace(struct buffer *b, char *pos, char *end, const char *str) len = strlen(str); delta = len - (end - pos); - if (delta + b->r >= b->data + BUFSIZE) + if (delta + b->r >= b->data + b->size) return 0; /* no space left */ /* first, protect the end of the buffer */ @@ -145,7 +145,7 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int delta = len - (end - pos); - if (delta + b->r >= b->data + BUFSIZE) + if (delta + b->r >= b->data + b->size) return 0; /* no space left */ if (b->data + b->l < end) { @@ -192,7 +192,7 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len) delta = len + 2; - if (delta + b->r >= b->data + BUFSIZE) + if (delta + b->r >= b->data + b->size) return 0; /* no space left */ /* first, protect the end of the buffer */ diff --git a/src/client.c b/src/client.c index ec8f12017..92baefc63 100644 --- a/src/client.c +++ b/src/client.c @@ -384,6 +384,7 @@ int event_accept(int fd) { if ((s->req = pool_alloc2(pool2_buffer)) == NULL) goto out_fail_req; /* no memory */ + s->req->size = BUFSIZE; buffer_init(s->req); s->req->prod = &s->si[0]; s->req->cons = &s->si[1]; @@ -410,6 +411,7 @@ int event_accept(int fd) { if ((s->rep = pool_alloc2(pool2_buffer)) == NULL) goto out_fail_rep; /* no memory */ + s->rep->size = BUFSIZE; buffer_init(s->rep); s->rep->prod = &s->si[1]; s->rep->cons = &s->si[0]; diff --git a/src/proto_http.c b/src/proto_http.c index e495d32bb..d2c591916 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2576,7 +2576,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit) * could. Let's switch to the DATA state. * ************************************************************/ - buffer_set_rlim(req, BUFSIZE); /* no more rewrite needed */ + buffer_set_rlim(req, req->size); /* no more rewrite needed */ s->logs.tv_request = now; /* When a connection is tarpitted, we use the tarpit timeout, @@ -3190,7 +3190,7 @@ int process_response(struct session *t) * could. Let's switch to the DATA state. * ************************************************************/ - buffer_set_rlim(rep, BUFSIZE); /* no more rewrite needed */ + buffer_set_rlim(rep, rep->size); /* no more rewrite needed */ t->logs.t_data = tv_ms_elapsed(&t->logs.tv_accept, &now); /* if the user wants to log as soon as possible, without counting diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 880ec993a..0cd6a3586 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -482,6 +482,7 @@ int uxst_event_accept(int fd) { if ((s->req = pool_alloc2(pool2_buffer)) == NULL) goto out_free_task; + s->req->size = BUFSIZE; buffer_init(s->req); s->req->prod = &s->si[0]; s->req->cons = &s->si[1]; @@ -498,6 +499,7 @@ int uxst_event_accept(int fd) { if ((s->rep = pool_alloc2(pool2_buffer)) == NULL) goto out_free_req; + s->rep->size = BUFSIZE; buffer_init(s->rep); s->rep->prod = &s->si[1]; diff --git a/src/session.c b/src/session.c index 33109d6c1..23c4409c6 100644 --- a/src/session.c +++ b/src/session.c @@ -320,7 +320,7 @@ void sess_establish(struct session *s, struct stream_interface *si) struct buffer *rep = si->ib; if (s->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */ - buffer_set_rlim(rep, BUFSIZE); /* no rewrite needed */ + buffer_set_rlim(rep, rep->size); /* no rewrite needed */ /* if the user wants to log as soon as possible, without counting * bytes from the server, then this is the right moment. */ @@ -330,7 +330,7 @@ void sess_establish(struct session *s, struct stream_interface *si) } } else { - buffer_set_rlim(rep, BUFSIZE - MAXREWRITE); /* rewrite needed */ + buffer_set_rlim(rep, req->size - MAXREWRITE); /* rewrite needed */ s->txn.rsp.msg_state = HTTP_MSG_RPBEFORE; /* reset hdr_idx which was already initialized by the request. * right now, the http parser does it. diff --git a/src/stream_sock.c b/src/stream_sock.c index f20bb3f0c..3a69d1f19 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -345,7 +345,7 @@ int stream_sock_read(int fd) { b->flags |= BF_READ_PARTIAL; b->flags &= ~BF_EMPTY; - if (b->r == b->data + BUFSIZE) { + if (b->r == b->data + b->size) { b->r = b->data; /* wrap around the buffer */ } @@ -367,7 +367,7 @@ int stream_sock_read(int fd) { } } else if ((b->flags & (BF_STREAMER | BF_STREAMER_FAST)) && - (cur_read <= BUFSIZE / 2)) { + (cur_read <= b->size / 2)) { b->xfer_large = 0; b->xfer_small++; if (b->xfer_small >= 2) { @@ -397,7 +397,7 @@ int stream_sock_read(int fd) { */ if (ret < max) { if ((b->flags & (BF_STREAMER | BF_STREAMER_FAST)) && - (cur_read <= BUFSIZE / 2)) { + (cur_read <= b->size / 2)) { b->xfer_large = 0; b->xfer_small++; if (b->xfer_small >= 3) { @@ -580,7 +580,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) if (b->r > b->w) max = b->r - b->w; else - max = b->data + BUFSIZE - b->w; + max = b->data + b->size - b->w; /* limit the amount of outgoing data if required */ if (max > b->send_max) @@ -628,7 +628,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) b->flags |= BF_WRITE_PARTIAL; b->w += ret; - if (b->w == b->data + BUFSIZE) + if (b->w == b->data + b->size) b->w = b->data; /* wrap around the buffer */ b->l -= ret;