[-]
[+]
|
Changed |
haproxy.spec
|
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/CHANGELOG
^
|
@@ -1,6 +1,23 @@
ChangeLog :
===========
+2016/05/10 : 1.5.18
+ - DOC: Clarify IPv4 address / mask notation rules
+ - CLEANUP: fix inconsistency between fd->iocb, proto->accept and accept()
+ - BUG/MEDIUM: fix maxaccept computation on per-process listeners
+ - BUG/MINOR: listener: stop unbound listeners on startup
+ - BUG/MINOR: fix maxaccept computation according to the frontend process range
+ - MEDIUM: unblock signals on startup.
+ - BUG/MEDIUM: channel: don't allow to overwrite the reserve until connected
+ - BUG/MEDIUM: channel: incorrect polling condition may delay event delivery
+ - BUG/MEDIUM: channel: fix miscalculation of available buffer space (3rd try)
+ - MINOR: channel: add new function channel_congested()
+ - BUG/MEDIUM: http: fix risk of CPU spikes with pipelined requests from dead client
+ - BUG/MAJOR: channel: fix miscalculation of available buffer space (4th try)
+ - BUG/MEDIUM: stream: ensure the SI_FL_DONT_WAKE flag is properly cleared
+ - BUG/MEDIUM: channel: fix inconsistent handling of 4GB-1 transfers
+ - MINOR: stats: fix typo in help messages
+
2016/04/13 : 1.5.17
- BUG/MINOR: log: Don't use strftime() which can clobber timezone if chrooted
- BUG/MINOR: conf: "listener id" expects integer, but its not checked
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/README
^
|
@@ -3,7 +3,7 @@
----------------------
version 1.5
willy tarreau
- 2016/04/13
+ 2016/05/10
1) How to build it
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/VERDATE
^
|
@@ -1,2 +1,2 @@
$Format:%ci$
-2016/04/13
+2016/05/10
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/VERSION
^
|
@@ -1 +1 @@
-1.5.17
+1.5.18
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/doc/configuration.txt
^
|
@@ -4,7 +4,7 @@
----------------------
version 1.5
willy tarreau
- 2016/04/13
+ 2016/05/10
This document covers the configuration language as implemented in the version
@@ -9850,6 +9850,21 @@
does not depend on any random DNS match at the moment the configuration is
parsed.
+The dotted IPv4 address notation is supported in both regular as well as the
+abbreviated form with all-0-octets omitted:
+
+ +------------------+------------------+------------------+
+ | Example 1 | Example 2 | Example 3 |
+ +------------------+------------------+------------------+
+ | 192.168.0.1 | 10.0.0.12 | 127.0.0.1 |
+ | 192.168.1 | 10.12 | 127.1 |
+ | 192.168.0.1/22 | 10.0.0.12/8 | 127.0.0.1/8 |
+ | 192.168.1/22 | 10.12/8 | 127.1/8 |
+ +------------------+------------------+------------------+
+
+Notice that this is different from RFC 4632 CIDR address notation in which
+192.168.42/24 would be equivalent to 192.168.42.0/24.
+
IPv6 may be entered in their usual form, with or without a netmask appended.
Only bit counts are accepted for IPv6 netmasks. In order to avoid any risk of
trouble with randomly resolved IP addresses, host names are never allowed in
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/examples/haproxy.spec
^
|
@@ -1,6 +1,6 @@
Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
Name: haproxy
-Version: 1.5.17
+Version: 1.5.18
Release: 1
License: GPL
Group: System Environment/Daemons
@@ -76,6 +76,9 @@
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
%changelog
+* Tue May 10 2016 Willy Tarreau <w@1wt.eu>
+- updated to 1.5.18
+
* Wed Apr 13 2016 Willy Tarreau <w@1wt.eu>
- updated to 1.5.17
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/include/proto/channel.h
^
|
@@ -90,6 +90,13 @@
return __channel_forward(chn, bytes);
}
+/* Forwards any input data and marks the channel for permanent forwarding */
+static inline void channel_forward_forever(struct channel *chn)
+{
+ b_adv(chn->buf, chn->buf->i);
+ chn->to_forward = CHN_INFINITE_FORWARD;
+}
+
/*********************************************************************/
/* These functions are used to compute various channel content sizes */
/*********************************************************************/
@@ -118,6 +125,27 @@
return rem >= 0;
}
+/* Returns non-zero if the channel is congested with data in transit waiting
+ * for leaving, indicating to the caller that it should wait for the reserve to
+ * be released before starting to process new data in case it needs the ability
+ * to append data. This is meant to be used while waiting for a clean response
+ * buffer before processing a request.
+ */
+static inline int channel_congested(const struct channel *chn)
+{
+ if (!chn->buf->o)
+ return 0;
+
+ if (!channel_reserved(chn))
+ return 1;
+
+ if (chn->buf->p + chn->buf->i >
+ chn->buf->data + chn->buf->size - global.tune.maxrewrite)
+ return 1;
+
+ return 0;
+}
+
/* Tells whether data are likely to leave the buffer. This is used to know when
* we can safely ignore the reserve since we know we cannot retry a connection.
* It returns zero if data are blocked, non-zero otherwise.
@@ -134,7 +162,9 @@
* end of transfer is close to happen. Note that both ->buf->o and ->to_forward
* are considered as available since they're supposed to leave the buffer. The
* test is optimized to avoid as many operations as possible for the fast case
- * and to be used as an "if" condition.
+ * and to be used as an "if" condition. Just like channel_recv_limit(), we
+ * never allow to overwrite the reserve until the output stream interface is
+ * connected, otherwise we could spin on a POST with http-send-name-header.
*/
static inline int channel_full(const struct channel *chn)
{
@@ -145,18 +175,14 @@
if (!rem)
return 1; /* buffer already full */
- /* now we know there's some room left, verify if we're touching
- * the reserve with some permanent input data.
- */
- if (chn->to_forward >= chn->buf->i ||
- (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf->i)) && // just there to ensure gcc
- chn->to_forward == CHN_INFINITE_FORWARD)) // avoids the useless second
- return 0; // test whenever possible
+ if (rem > global.tune.maxrewrite)
+ return 0;
- rem -= global.tune.maxrewrite;
- rem += chn->buf->o;
- rem += chn->to_forward;
- return rem <= 0;
+ if (!channel_may_send(chn))
+ return 1;
+
+ rem = chn->buf->i + global.tune.maxrewrite - chn->buf->size;
+ return rem >= 0 && (unsigned int)rem >= chn->to_forward;
}
/* Returns true if the channel's input is already closed */
@@ -269,26 +295,65 @@
/* Return the max number of bytes the buffer can contain so that once all the
* pending bytes are forwarded, the buffer still has global.tune.maxrewrite
* bytes free. The result sits between chn->size - maxrewrite and chn->size.
- * The principle is the following :
- * - a non-connected buffer cannot touch the reserve
- * - infinite forward can fill the buffer
- * - all output bytes are ignored, they're leaving
- * - all input bytes covered by to_forward are considered in transit and
- * virtually don't take room
- * - the reserve may be covered up to the min of (fwd-transit) since these
- * bytes will be in transit later thus will only take temporary space.
- *
- * So the formula is to return this limit is :
- * size - maxrewrite + min(fwd - min(i, fwd), maxrewrite)
- * = size - maxrewrite + min( min(fwd - i, 0), maxrewrite)
- *
- * The code isn't written the most obvious way because we help the compiler
- * optimise it as it cannot guess how to factor the result out. The most common
- * path is jumpless.
+ * It is important to mention that if buf->i is already larger than size-maxrw
+ * the condition above cannot be satisfied and the lowest size will be returned
+ * anyway. The principles are the following :
+ * 1) a non-connected buffer cannot touch the reserve
+ * 2) infinite forward can always fill the buffer since all data will leave
+ * 3) all output bytes are considered in transit since they're leaving
+ * 4) all input bytes covered by to_forward are considered in transit since
+ * they'll be converted to output bytes.
+ * 5) all input bytes not covered by to_forward as considered remaining
+ * 6) all bytes scheduled to be forwarded minus what is already in the input
+ * buffer will be in transit during future rounds.
+ * 7) 4+5+6 imply that the amount of input bytes (i) is irrelevant to the max
+ * usable length, only to_forward and output count. The difference is
+ * visible when to_forward > i.
+ * 8) the reserve may be covered up to the amount of bytes in transit since
+ * these bytes will only take temporary space.
+ *
+ * A typical buffer looks like this :
+ *
+ * <-------------- max_len ----------->
+ * <---- o ----><----- i -----> <--- 0..maxrewrite --->
+ * +------------+--------------+-------+----------------------+
+ * |////////////|\\\\\\\\\\\\\\|xxxxxxx| reserve |
+ * +------------+--------+-----+-------+----------------------+
+ * <- fwd -> <-avail->
+ *
+ * Or when to_forward > i :
+ *
+ * <-------------- max_len ----------->
+ * <---- o ----><----- i -----> <--- 0..maxrewrite --->
+ * +------------+--------------+-------+----------------------+
+ * |////////////|\\\\\\\\\\\\\\|xxxxxxx| reserve |
+ * +------------+--------+-----+-------+----------------------+
+ * <-avail->
+ * <------------------ fwd ---------------->
+ *
+ * - the amount of buffer bytes in transit is : min(i, fwd) + o
+ * - some scheduled bytes may be in transit (up to fwd - i)
+ * - the reserve is max(0, maxrewrite - transit)
+ * - the maximum usable buffer length is size - reserve.
+ * - the available space is max_len - i - o
+ *
+ * So the formula to compute the buffer's maximum length to protect the reserve
+ * when reading new data is :
+ *
+ * max = size - maxrewrite + min(maxrewrite, transit)
+ * = size - max(maxrewrite - transit, 0)
+ *
+ * But WARNING! The conditions might change during the transfer and it could
+ * very well happen that a buffer would contain more bytes than max_len due to
+ * i+o already walking over the reserve (eg: after a header rewrite), including
+ * i or o alone hitting the limit. So it is critical to always consider that
+ * bounds may have already been crossed and that available space may be negative
+ * for example. Due to this it is perfectly possible for this function to return
+ * a value that is lower than current i+o.
*/
static inline int buffer_max_len(const struct channel *chn)
{
- int transit;
+ unsigned int transit;
int reserve;
/* return size - maxrewrite if we can't send */
@@ -296,21 +361,20 @@
if (unlikely(!channel_may_send(chn)))
goto end;
- /* This apparently tricky check is just a hint to let the compiler
- * optimize all this code away as long as we don't change the types.
+ /* We need to check what remains of the reserve after o and to_forward
+ * have been transmitted, but they can overflow together and they can
+ * cause an integer underflow in the comparison since both are unsigned
+ * while maxrewrite is signed.
+ * The code below has been verified for being a valid check for this :
+ * - if (o + to_forward) overflow => return size [ large enough ]
+ * - if o + to_forward >= maxrw => return size [ large enough ]
+ * - otherwise return size - (maxrw - (o + to_forward))
*/
- reserve = 0;
- if (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf->i)) &&
- chn->to_forward == CHN_INFINITE_FORWARD)
- goto end;
-
- transit = chn->buf->o + chn->to_forward - chn->buf->i;
- if (transit < 0)
- transit = 0;
-
- reserve = global.tune.maxrewrite - transit;
- if (reserve < 0)
- reserve = 0;
+ transit = chn->buf->o + chn->to_forward;
+ reserve -= transit;
+ if (transit < chn->to_forward || // addition overflow
+ transit >= (unsigned)global.tune.maxrewrite) // enough transit data
+ return chn->buf->size;
end:
return chn->buf->size - reserve;
}
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/include/proto/connection.h
^
|
@@ -35,9 +35,9 @@
int init_connection();
/* I/O callback for fd-based connections. It calls the read/write handlers
- * provided by the connection's sock_ops. Returns 0.
+ * provided by the connection's sock_ops.
*/
-int conn_fd_handler(int fd);
+void conn_fd_handler(int fd);
/* receive a PROXY protocol header over a connection */
int conn_recv_proxy(struct connection *conn, int flag);
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/include/proto/listener.h
^
|
@@ -105,7 +105,7 @@
* to an accept. It tries to accept as many connections as possible, and for each
* calls the listener's accept handler (generally the frontend's accept handler).
*/
-int listener_accept(int fd);
+void listener_accept(int fd);
/*
* Registers the bind keyword list <kwl> as a list of valid keywords for next
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/include/types/fd.h
^
|
@@ -78,7 +78,7 @@
/* info about one given fd */
struct fdtab {
- int (*iocb)(int fd); /* I/O handler, returns FD_WAIT_* */
+ void (*iocb)(int fd); /* I/O handler */
void *owner; /* the connection or listener associated with this fd, NULL if closed */
unsigned int cache; /* position+1 in the FD cache. 0=not in cache. */
unsigned char state; /* FD state for read and write directions (2*3 bits) */
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/include/types/protocol.h
^
|
@@ -50,7 +50,7 @@
sa_family_t sock_family; /* socket family, for sockaddr */
socklen_t sock_addrlen; /* socket address length, used by bind() */
int l3_addrlen; /* layer3 address length, used by hashes */
- int (*accept)(int fd); /* generic accept function */
+ void (*accept)(int fd); /* generic accept function */
int (*bind)(struct listener *l, char *errmsg, int errlen); /* bind a listener */
int (*bind_all)(struct protocol *proto, char *errmsg, int errlen); /* bind all unbound listeners */
int (*unbind_all)(struct protocol *proto); /* unbind all bound listeners */
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/cfgparse.c
^
|
@@ -7179,9 +7179,6 @@
for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
struct listener *listener;
unsigned int next_id;
- int nbproc;
-
- nbproc = my_popcountl(curproxy->bind_proc & nbits(global.nbproc));
#ifdef USE_OPENSSL
/* Configure SSL for each bind line.
@@ -7223,6 +7220,15 @@
/* adjust this proxy's listeners */
next_id = 1;
list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
+ int nbproc;
+
+ nbproc = my_popcountl(curproxy->bind_proc &
+ (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
+ nbits(global.nbproc));
+
+ if (!nbproc) /* no intersection between listener and frontend */
+ nbproc = 1;
+
if (!listener->luid) {
/* listener ID not set, use automatic numbering with first
* spare entry starting with next_luid.
@@ -7293,7 +7299,7 @@
#endif /* USE_OPENSSL */
}
- if (nbproc > 1) {
+ if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
if (curproxy->uri_auth) {
int count, maxproc = 0;
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/channel.c
^
|
@@ -33,44 +33,49 @@
/* Schedule up to <bytes> more bytes to be forwarded via the channel without
* notifying the owner task. Any data pending in the buffer are scheduled to be
- * sent as well, in the limit of the number of bytes to forward. This must be
- * the only method to use to schedule bytes to be forwarded. If the requested
+ * sent as well, within the limit of the number of bytes to forward. This must
+ * be the only method to use to schedule bytes to be forwarded. If the requested
* number is too large, it is automatically adjusted. The number of bytes taken
* into account is returned. Directly touching ->to_forward will cause lockups
* when buf->o goes down to zero if nobody is ready to push the remaining data.
*/
unsigned long long __channel_forward(struct channel *chn, unsigned long long bytes)
{
- unsigned int new_forward;
+ unsigned int budget;
unsigned int forwarded;
- forwarded = chn->buf->i;
- b_adv(chn->buf, chn->buf->i);
-
- /* Note: the case below is the only case where we may return
- * a byte count that does not fit into a 32-bit number.
+ /* This is more of a safety measure as it's not supposed to happen in
+ * regular code paths.
*/
- if (likely(chn->to_forward == CHN_INFINITE_FORWARD))
- return bytes;
-
- if (likely(bytes == CHN_INFINITE_FORWARD)) {
- chn->to_forward = bytes;
+ if (unlikely(chn->to_forward == CHN_INFINITE_FORWARD)) {
+ b_adv(chn->buf, chn->buf->i);
return bytes;
}
- new_forward = chn->to_forward + bytes - forwarded;
- bytes = forwarded; /* at least those bytes were scheduled */
+ /* Bound the transferred size to a 32-bit count since all our values
+ * are 32-bit, and we don't want to reach CHN_INFINITE_FORWARD.
+ */
+ budget = MIN(bytes, CHN_INFINITE_FORWARD - 1);
+
+ /* transfer as much as we can of buf->i */
+ forwarded = MIN(chn->buf->i, budget);
+ b_adv(chn->buf, forwarded);
+ budget -= forwarded;
- if (new_forward <= chn->to_forward) {
- /* integer overflow detected, let's assume no more than 2G at once */
- new_forward = MID_RANGE(new_forward);
- }
+ if (!budget)
+ return forwarded;
- if (new_forward > chn->to_forward) {
- bytes += new_forward - chn->to_forward;
- chn->to_forward = new_forward;
- }
- return bytes;
+ /* Now we must ensure chn->to_forward sats below CHN_INFINITE_FORWARD,
+ * which also implies it won't overflow. It's less operations in 64-bit.
+ */
+ bytes = (unsigned long long)chn->to_forward + budget;
+ if (bytes >= CHN_INFINITE_FORWARD)
+ bytes = CHN_INFINITE_FORWARD - 1;
+ budget = bytes - chn->to_forward;
+
+ chn->to_forward += budget;
+ forwarded += budget;
+ return forwarded;
}
/* writes <len> bytes from message <msg> to the channel's buffer. Returns -1 in
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/connection.c
^
|
@@ -36,15 +36,15 @@
}
/* I/O callback for fd-based connections. It calls the read/write handlers
- * provided by the connection's sock_ops, which must be valid. It returns 0.
+ * provided by the connection's sock_ops, which must be valid.
*/
-int conn_fd_handler(int fd)
+void conn_fd_handler(int fd)
{
struct connection *conn = fdtab[fd].owner;
unsigned int flags;
if (unlikely(!conn))
- return 0;
+ return;
conn_refresh_polling_flags(conn);
flags = conn->flags & ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
@@ -86,7 +86,7 @@
* we must not use it anymore and should immediately leave instead.
*/
if ((conn->flags & CO_FL_INIT_DATA) && conn->data->init(conn) < 0)
- return 0;
+ return;
/* The data transfer starts here and stops on error and handshakes. Note
* that we must absolutely test conn->xprt at each step in case it suddenly
@@ -133,7 +133,7 @@
if ((conn->flags & CO_FL_WAKE_DATA) &&
((conn->flags ^ flags) & CO_FL_CONN_STATE) &&
conn->data->wake(conn) < 0)
- return 0;
+ return;
/* Last check, verify if the connection just established */
if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
@@ -144,7 +144,7 @@
/* commit polling changes */
conn_cond_update_polling(conn);
- return 0;
+ return;
}
/* Update polling on connection <c>'s file descriptor depending on its current
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/dumpstats.c
^
|
@@ -81,7 +81,7 @@
STAT_CLI_O_CLR, /* clear tables */
STAT_CLI_O_SET, /* set entries in tables */
STAT_CLI_O_STAT, /* dump stats */
- STAT_CLI_O_PATS, /* list all pattern reference avalaible */
+ STAT_CLI_O_PATS, /* list all pattern reference available */
STAT_CLI_O_PAT, /* list all entries of a pattern */
STAT_CLI_O_MLOOK, /* lookup a map entry */
STAT_CLI_O_POOLS, /* dump memory pools */
@@ -186,12 +186,12 @@
" disable : put a server or frontend in maintenance mode\n"
" enable : re-enable a server or frontend which is in maintenance mode\n"
" shutdown : kill a session or a frontend (eg:to release listening ports)\n"
- " show acl [id] : report avalaible acls or dump an acl's contents\n"
+ " show acl [id] : report available acls or dump an acl's contents\n"
" get acl : reports the patterns matching a sample for an ACL\n"
" add acl : add acl entry\n"
" del acl : delete acl entry\n"
" clear acl <id> : clear the content of this acl\n"
- " show map [id] : report avalaible maps or dump a map's contents\n"
+ " show map [id] : report available maps or dump a map's contents\n"
" get map : reports the keys and values matching a sample for a map\n"
" set map : modify map entry\n"
" add map : add map entry\n"
@@ -1175,7 +1175,7 @@
else
appctx->ctx.map.display_flags = PAT_REF_ACL;
- /* no parameter: display all map avalaible */
+ /* no parameter: display all map available */
if (!*args[2]) {
appctx->st2 = STAT_ST_INIT;
appctx->st0 = STAT_CLI_O_PATS;
@@ -5300,8 +5300,8 @@
/* Now, we start the browsing of the references lists.
* Note that the following call to LIST_ELEM return bad pointer. The only
- * avalaible field of this pointer is <list>. It is used with the function
- * pat_list_get_next() for retruning the first avalaible entry
+ * available field of this pointer is <list>. It is used with the function
+ * pat_list_get_next() for retruning the first available entry
*/
appctx->ctx.map.ref = LIST_ELEM(&pattern_reference, struct pat_ref *, list);
appctx->ctx.map.ref = pat_list_get_next(appctx->ctx.map.ref, &pattern_reference,
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/listener.c
^
|
@@ -32,6 +32,7 @@
#include <proto/fd.h>
#include <proto/freq_ctr.h>
#include <proto/log.h>
+#include <proto/listener.h>
#include <proto/sample.h>
#include <proto/task.h>
@@ -55,8 +56,7 @@
/* we don't want to enable this listener and don't
* want any fd event to reach it.
*/
- fd_stop_recv(listener->fd);
- listener->state = LI_PAUSED;
+ unbind_listener(listener);
}
else if (listener->nbconn < listener->maxconn) {
fd_want_recv(listener->fd);
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/proto_http.c
^
|
@@ -5310,9 +5310,18 @@
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)) {
/* server-close/keep-alive: terminate this transaction,
* possibly killing the server connection and reinitialize
- * a fresh-new transaction.
+ * a fresh-new transaction, but only once we're sure there's
+ * enough room in the request and response buffer to process
+ * another request. The request buffer must not hold any
+ * pending output data and the request buffer must not have
+ * output data occupying the reserve.
*/
- http_end_txn_clean_session(s);
+ if (s->req->buf->o)
+ s->req->flags |= CF_WAKE_WRITE;
+ else if (channel_congested(s->rep))
+ s->rep->flags |= CF_WAKE_WRITE;
+ else
+ http_end_txn_clean_session(s);
}
return txn->req.msg_state != old_req_state ||
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/session.c
^
|
@@ -1707,8 +1707,11 @@
(CF_SHUTR|CF_READ_ACTIVITY|CF_READ_TIMEOUT|CF_SHUTW|
CF_WRITE_ACTIVITY|CF_WRITE_TIMEOUT|CF_ANA_TIMEOUT)) &&
!((s->si[0].flags | s->si[1].flags) & (SI_FL_EXP|SI_FL_ERR)) &&
- ((t->state & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER))
+ ((t->state & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER)) {
+ s->si[0].flags &= ~SI_FL_DONT_WAKE;
+ s->si[1].flags &= ~SI_FL_DONT_WAKE;
goto update_exp_and_leave;
+ }
}
/* 1b: check for low-level errors reported at the stream interface.
@@ -2183,7 +2186,7 @@
* to the consumer (which might possibly not be connected yet).
*/
if (!(s->req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
- channel_forward(s->req, CHN_INFINITE_FORWARD);
+ channel_forward_forever(s->req);
}
/* check if it is wise to enable kernel splicing to forward request data */
@@ -2330,7 +2333,7 @@
* to the consumer.
*/
if (!(s->rep->flags & (CF_SHUTR|CF_SHUTW_NOW)))
- channel_forward(s->rep, CHN_INFINITE_FORWARD);
+ channel_forward_forever(s->rep);
/* if we have no analyser anymore in any direction and have a
* tunnel timeout set, use it now. Note that we must respect
|
[-]
[+]
|
Changed |
_service:download_files:haproxy-1.5.18.tar.gz/src/signal.c
^
|
@@ -105,6 +105,14 @@
signal_queue_len = 0;
memset(signal_queue, 0, sizeof(signal_queue));
memset(signal_state, 0, sizeof(signal_state));
+
+ /* Ensure signals are not blocked. Some shells or service managers may
+ * accidently block all of our signals unfortunately, causing lots of
+ * zombie processes to remain in the background during reloads.
+ */
+ sigemptyset(&blocked_sig);
+ sigprocmask(SIG_SETMASK, &blocked_sig, NULL);
+
sigfillset(&blocked_sig);
sigdelset(&blocked_sig, SIGPROF);
for (sig = 0; sig < MAX_SIGNAL; sig++)
|