[-]
[+]
|
Changed |
_service
|
@@ -3,5 +3,5 @@
- <param name="protocol">http</param><param name="host">haproxy.1wt.eu</param><param name="path">/download/1.5/src/haproxy-1.5.3.tar.gz</param></service>
+ <param name="protocol">http</param><param name="host">haproxy.1wt.eu</param><param name="path">/download/1.5/src/haproxy-1.5.5.tar.gz</param></service>
</services>
\ No newline at end of file
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/.gitignore
^
|
@@ -12,6 +12,7 @@
*.log*
*.trace*
haproxy-*
+!doc/haproxy-*.txt
!src/*.c
make-*
dlmalloc.c
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/CHANGELOG
^
|
@@ -1,6 +1,46 @@
ChangeLog :
===========
+2014/10/08 : 1.5.5
+ - DOC: Address issue where documentation is excluded due to a gitignore rule.
+ - MEDIUM: Improve signal handling in systemd wrapper.
+ - BUG/MINOR: config: don't propagate process binding for dynamic use_backend
+ - MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper
+ - DOC: clearly state that the "show sess" output format is not fixed
+ - MINOR: stats: fix minor typo fix in stats_dump_errors_to_buffer()
+ - DOC: indicate in the doc that track-sc* can wait if data are missing
+ - MEDIUM: http: enable header manipulation for 101 responses
+ - BUG/MEDIUM: config: propagate frontend to backend process binding again.
+ - MEDIUM: config: properly propagate process binding between proxies
+ - MEDIUM: config: make the frontends automatically bind to the listeners' processes
+ - MEDIUM: config: compute the exact bind-process before listener's maxaccept
+ - MEDIUM: config: only warn if stats are attached to multi-process bind directives
+ - MEDIUM: config: report it when tcp-request rules are misplaced
+ - MINOR: config: detect the case where a tcp-request content rule has no inspect-delay
+ - MEDIUM: systemd-wrapper: support multiple executable versions and names
+ - BUG/MEDIUM: remove debugging code from systemd-wrapper
+ - BUG/MEDIUM: http: adjust close mode when switching to backend
+ - BUG/MINOR: config: don't propagate process binding on fatal errors.
+ - BUG/MEDIUM: check: rule-less tcp-check must detect connect failures
+ - BUG/MINOR: tcp-check: report the correct failed step in the status
+ - DOC: indicate that weight zero is reported as DRAIN
+
+2014/09/02 : 1.5.4
+ - BUG: config: error in http-response replace-header number of arguments
+ - BUG/MINOR: Fix search for -p argument in systemd wrapper.
+ - BUG/MEDIUM: auth: fix segfault with http-auth and a configuration with an unknown encryption algorithm
+ - BUG/MEDIUM: config: userlists should ensure that encrypted passwords are supported
+ - MEDIUM: connection: add new bit in Proxy Protocol V2
+ - BUG/MINOR: server: move the directive #endif to the end of file
+ - BUG/MEDIUM: http: tarpit timeout is reset
+ - BUG/MAJOR: tcp: fix a possible busy spinning loop in content track-sc*
+ - BUG/MEDIUM: http: fix inverted condition in pat_match_meth()
+ - BUG/MEDIUM: http: fix improper parsing of HTTP methods for use with ACLs
+ - BUG/MINOR: pattern: remove useless allocation of unused trash in pat_parse_reg()
+ - BUG/MEDIUM: acl: correctly compute the output type when a converter is used
+ - CLEANUP: acl: cleanup some of the redundancy and spaghetti after last fix
+ - BUG/CRITICAL: http: don't update msg->sov once data start to leave the buffer
+
2014/07/25 : 1.5.3
- DOC: fix typo in Unix Socket commands
- BUG/MEDIUM: connection: fix memory corruption when building a proxy v2 header
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/README
^
|
@@ -1,9 +1,9 @@
----------------------
HAProxy how-to
----------------------
- version 1.5.3
+ version 1.5.4
willy tarreau
- 2014/07/25
+ 2014/09/02
1) How to build it
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/VERDATE
^
|
@@ -1,2 +1,2 @@
$Format:%ci$
-2014/07/25
+2014/10/07
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/VERSION
^
|
@@ -1 +1 @@
-1.5.3
+1.5.5
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/doc/configuration.txt
^
|
@@ -2,9 +2,9 @@
HAProxy
Configuration Manual
----------------------
- version 1.5.3
+ version 1.5.4
willy tarreau
- 2014/07/25
+ 2014/09/02
This document covers the configuration language as implemented in the version
@@ -1905,6 +1905,10 @@
Each "bind" line may further be limited to a subset of the proxy's processes,
please consult the "process" bind keyword in section 5.1.
+ When a frontend has no explicit "bind-process" line, it tries to bind to all
+ the processes referenced by its "bind" lines. That means that frontends can
+ easily adapt to their listeners' processes.
+
If some backends are referenced by frontends bound to other processes, the
backend automatically inherits the frontend's processes.
@@ -7470,9 +7474,9 @@
contents will always be immediately present when the rule is evaluated first.
Tracking layer7 information is also possible provided that the information
- are present when the rule is processed. The current solution for making the
- rule engine wait for such information is to set an inspect delay and to
- condition its execution with an ACL relying on such information.
+ are present when the rule is processed. The rule processing engine is able to
+ wait until the inspect delay expires when the data to be tracked is not yet
+ available.
Example:
# Accept HTTP requests containing a Host header saying "example.com"
@@ -7497,12 +7501,12 @@
Example:
# Track the last IP from X-Forwarded-For
tcp-request inspect-delay 10s
- tcp-request content track-sc0 hdr(x-forwarded-for,-1) if HTTP
+ tcp-request content track-sc0 hdr(x-forwarded-for,-1)
Example:
# track request counts per "base" (concatenation of Host+URL)
tcp-request inspect-delay 10s
- tcp-request content track-sc0 base table req-rate if HTTP
+ tcp-request content track-sc0 base table req-rate
Example: track per-frontend and per-backend counters, block abusers at the
frontend when the backend detects abuse.
@@ -8645,7 +8649,9 @@
- An ASCII representation of a positive integer percentage, e.g. "75%".
Values in this format will set the weight proportional to the initial
- weight of a server as configured when haproxy starts.
+ weight of a server as configured when haproxy starts. Note that a zero
+ weight is reported on the stats page as "DRAIN" since it has the same
+ effect on the server (it's removed from the LB farm).
- The word "ready". This will turn the server's administrative state to the
READY mode, thus cancelling any DRAIN or MAINT state
@@ -13734,9 +13740,11 @@
of "show sess" (it corresponds to the session pointer). Those information are
useless to most users but may be used by haproxy developers to troubleshoot a
complex bug. The output format is intentionally not documented so that it can
- freely evolve depending on demands. The special id "all" dumps the states of
- all sessions, which can be avoided as much as possible as it is highly CPU
- intensive and can take a lot of time.
+ freely evolve depending on demands. You may find a description of all fields
+ returned in src/dumpstats.c
+
+ The special id "all" dumps the states of all sessions, which must be avoided
+ as much as possible as it is highly CPU intensive and can take a lot of time.
show stat [<iid> <type> <sid>]
Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.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.3
+Version: 1.5.5
Release: 1
License: GPL
Group: System Environment/Daemons
@@ -76,6 +76,12 @@
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
%changelog
+* Wed Oct 8 2014 Willy Tarreau <w@1wt.eu>
+- updated to 1.5.5
+
+* Tue Sep 2 2014 Willy Tarreau <w@1wt.eu>
+- updated to 1.5.4
+
* Fri Jul 25 2014 Willy Tarreau <w@1wt.eu>
- updated to 1.5.3
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/common/cfgparse.h
^
|
@@ -73,6 +73,8 @@
int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err);
int cfg_register_section(char *section_name,
int (*section_parser)(const char *, int, char **, int));
+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg);
+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg);
/*
* Sends a warning if proxy <proxy> does not have at least one of the
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/proto/proto_http.h
^
|
@@ -112,6 +112,7 @@
void http_init_txn(struct session *s);
void http_end_txn(struct session *s);
void http_reset_txn(struct session *s);
+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg);
struct http_req_rule *parse_http_req_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
struct http_res_rule *parse_http_res_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/proto/server.h
^
|
@@ -54,8 +54,6 @@
s->counters.last_sess = now.tv_sec;
}
-#endif /* _PROTO_SERVER_H */
-
/*
* Registers the server keyword list <kwl> as a list of valid keywords for next
* parsing sessions.
@@ -200,6 +198,8 @@
srv_clr_admin_flag(s, SRV_ADMF_FMAINT);
}
+#endif /* _PROTO_SERVER_H */
+
/*
* Local variables:
* c-indent-level: 8
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/proto/ssl_sock.h
^
|
@@ -51,7 +51,8 @@
const char *ssl_sock_get_cipher_name(struct connection *conn);
const char *ssl_sock_get_proto_version(struct connection *conn);
char *ssl_sock_get_version(struct connection *conn);
-int ssl_sock_get_cert_used(struct connection *conn);
+int ssl_sock_get_cert_used_sess(struct connection *conn);
+int ssl_sock_get_cert_used_conn(struct connection *conn);
int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *out);
unsigned int ssl_sock_get_verify_result(struct connection *conn);
#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/types/channel.h
^
|
@@ -105,7 +105,7 @@
#define CF_STREAMER 0x00010000 /* the producer is identified as streaming data */
#define CF_STREAMER_FAST 0x00020000 /* the consumer seems to eat the stream very fast */
-/* unused: 0x00040000 */
+#define CF_WROTE_DATA 0x00040000 /* some data were sent from this buffer */
#define CF_ANA_TIMEOUT 0x00080000 /* the analyser timeout has expired */
#define CF_READ_ATTACHED 0x00100000 /* the read side is attached for the first time */
#define CF_KERN_SPLICING 0x00200000 /* kernel splicing desired for this channel */
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/include/types/connection.h
^
|
@@ -345,8 +345,9 @@
uint8_t sub_tlv[0];
}__attribute__((packed));
-#define PP2_CLIENT_SSL 0x01
-#define PP2_CLIENT_CERT 0x02
+#define PP2_CLIENT_SSL 0x01
+#define PP2_CLIENT_CERT_CONN 0x02
+#define PP2_CLIENT_CERT_SESS 0x04
#endif /* _TYPES_CONNECTION_H */
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/acl.c
^
|
@@ -145,7 +145,6 @@
const char *begw;
const char *endw;
const char *endt;
- unsigned long prev_type;
int cur_type;
int nbargs;
int operator = STD_OP_EQ;
@@ -161,6 +160,7 @@
struct pat_ref *ref;
struct pattern_expr *pattern_expr;
int load_as_map = 0;
+ int acl_conv_found = 0;
/* First, we look for an ACL keyword. And if we don't find one, then
* we look for a sample fetch expression starting with a sample fetch
@@ -229,8 +229,10 @@
/* look for the begining of the converters list. Those directly attached
* to the ACL keyword are found just after <arg> which points to the comma.
+ * If we find any converter, then we don't use the ACL keyword's match
+ * anymore but the one related to the converter's output type.
*/
- prev_type = smp->fetch->out_type;
+ cur_type = smp->fetch->out_type;
while (*arg) {
struct sample_conv *conv;
struct sample_conv_expr *conv_expr;
@@ -289,19 +291,20 @@
}
/* If impossible type conversion */
- if (!sample_casts[prev_type][conv->in_type]) {
+ if (!sample_casts[cur_type][conv->in_type]) {
memprintf(err, "ACL keyword '%s' : conv method '%s' cannot be applied.",
aclkw->kw, ckw);
goto out_free_smp;
}
- prev_type = conv->out_type;
+ cur_type = conv->out_type;
conv_expr = calloc(1, sizeof(struct sample_conv_expr));
if (!conv_expr)
goto out_free_smp;
LIST_ADDQ(&(smp->conv_exprs), &(conv_expr->list));
conv_expr->conv = conv;
+ acl_conv_found = 1;
if (arg != endw) {
int err_arg;
@@ -347,6 +350,7 @@
memprintf(err, "%s in ACL expression '%s'", *err, *args);
goto out_return;
}
+ cur_type = smp_expr_output_type(smp);
}
expr = (struct acl_expr *)calloc(1, sizeof(*expr));
@@ -357,38 +361,26 @@
pattern_init_head(&expr->pat);
- expr->kw = aclkw ? aclkw->kw : smp->fetch->kw;
- expr->pat.parse = aclkw ? aclkw->parse : NULL;
- expr->pat.index = aclkw ? aclkw->index : NULL;
- expr->pat.match = aclkw ? aclkw->match : NULL;
- expr->pat.delete = aclkw ? aclkw->delete : NULL;
- expr->pat.prune = aclkw ? aclkw->prune : NULL;
- expr->pat.expect_type = smp->fetch->out_type;
- expr->smp = smp;
- smp = NULL;
-
- /* Fill NULL pointers with values provided by the pattern.c arrays */
- if (aclkw) {
- if (!expr->pat.parse)
- expr->pat.parse = pat_parse_fcts[aclkw->match_type];
-
- if (!expr->pat.index)
- expr->pat.index = pat_index_fcts[aclkw->match_type];
-
- if (!expr->pat.match)
- expr->pat.match = pat_match_fcts[aclkw->match_type];
-
- if (!expr->pat.delete)
- expr->pat.delete = pat_delete_fcts[aclkw->match_type];
-
- if (!expr->pat.prune)
- expr->pat.prune = pat_prune_fcts[aclkw->match_type];
+ expr->pat.expect_type = cur_type;
+ expr->smp = smp;
+ expr->kw = smp->fetch->kw;
+ smp = NULL; /* don't free it anymore */
+
+ if (aclkw && !acl_conv_found) {
+ expr->kw = aclkw->kw;
+ expr->pat.parse = aclkw->parse ? aclkw->parse : pat_parse_fcts[aclkw->match_type];
+ expr->pat.index = aclkw->index ? aclkw->index : pat_index_fcts[aclkw->match_type];
+ expr->pat.match = aclkw->match ? aclkw->match : pat_match_fcts[aclkw->match_type];
+ expr->pat.delete = aclkw->delete ? aclkw->delete : pat_delete_fcts[aclkw->match_type];
+ expr->pat.prune = aclkw->prune ? aclkw->prune : pat_prune_fcts[aclkw->match_type];
}
if (!expr->pat.parse) {
- /* some types can be automatically converted */
-
- switch (expr->smp ? expr->smp->fetch->out_type : aclkw->smp->out_type) {
+ /* Parse/index/match functions depend on the expression type,
+ * so we have to map them now. Some types can be automatically
+ * converted.
+ */
+ switch (cur_type) {
case SMP_T_BOOL:
expr->pat.parse = pat_parse_fcts[PAT_MATCH_BOOL];
expr->pat.index = pat_index_fcts[PAT_MATCH_BOOL];
@@ -427,7 +419,6 @@
}
/* Additional check to protect against common mistakes */
- cur_type = smp_expr_output_type(expr->smp);
if (expr->pat.parse && cur_type != SMP_T_BOOL && !*args[1]) {
Warning("parsing acl keyword '%s' :\n"
" no pattern to match against were provided, so this ACL will never match.\n"
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/auth.c
^
|
@@ -252,7 +252,7 @@
fprintf(stderr, ", crypt=%s\n", ep);
#endif
- if (!strcmp(ep, u->pass))
+ if (ep && strcmp(ep, u->pass) == 0)
return 1;
else
return 0;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/cfgparse.c
^
|
@@ -10,6 +10,16 @@
*
*/
+#ifdef CONFIG_HAP_CRYPT
+/* This is to have crypt() defined on Linux */
+#define _GNU_SOURCE
+
+#ifdef NEED_CRYPT_H
+/* some platforms such as Solaris need this */
+#include <crypt.h>
+#endif
+#endif /* CONFIG_HAP_CRYPT */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -307,6 +317,19 @@
return 0;
}
+/* Report a warning if a rule is placed after a 'tcp-request content' rule.
+ * Return 1 if the warning has been emitted, otherwise 0.
+ */
+int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
+{
+ if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
+ Warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
+ file, line, arg);
+ return 1;
+ }
+ return 0;
+}
+
/* Report a warning if a rule is placed after a 'block' rule.
* Return 1 if the warning has been emitted, otherwise 0.
*/
@@ -398,6 +421,31 @@
return 0;
}
+/* report a warning if a "tcp request connection" rule is dangerously placed */
+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
+{
+ return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
+ warnif_rule_after_block(proxy, file, line, arg) ||
+ warnif_rule_after_http_req(proxy, file, line, arg) ||
+ warnif_rule_after_reqxxx(proxy, file, line, arg) ||
+ warnif_rule_after_reqadd(proxy, file, line, arg) ||
+ warnif_rule_after_redirect(proxy, file, line, arg) ||
+ warnif_rule_after_use_backend(proxy, file, line, arg) ||
+ warnif_rule_after_use_server(proxy, file, line, arg);
+}
+
+/* report a warning if a "tcp request content" rule is dangerously placed */
+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
+{
+ return warnif_rule_after_block(proxy, file, line, arg) ||
+ warnif_rule_after_http_req(proxy, file, line, arg) ||
+ warnif_rule_after_reqxxx(proxy, file, line, arg) ||
+ warnif_rule_after_reqadd(proxy, file, line, arg) ||
+ warnif_rule_after_redirect(proxy, file, line, arg) ||
+ warnif_rule_after_use_backend(proxy, file, line, arg) ||
+ warnif_rule_after_use_server(proxy, file, line, arg);
+}
+
/* report a warning if a block rule is dangerously placed */
int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
{
@@ -5689,7 +5737,14 @@
while (*args[cur_arg]) {
if (!strcmp(args[cur_arg], "password")) {
-#ifndef CONFIG_HAP_CRYPT
+#ifdef CONFIG_HAP_CRYPT
+ if (!crypt("", args[cur_arg + 1])) {
+ Alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
+ file, linenum, newuser->user);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+#else
Warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
file, linenum);
err_code |= ERR_ALERT;
@@ -5915,6 +5970,66 @@
return err_code;
}
+/* This function propagates processes from frontend <from> to backend <to> so
+ * that it is always guaranteed that a backend pointed to by a frontend is
+ * bound to all of its processes. After that, if the target is a "listen"
+ * instance, the function recursively descends the target's own targets along
+ * default_backend, use_backend rules, and reqsetbe rules. Since the bits are
+ * checked first to ensure that <to> is already bound to all processes of
+ * <from>, there is no risk of looping and we ensure to follow the shortest
+ * path to the destination.
+ *
+ * It is possible to set <to> to NULL for the first call so that the function
+ * takes care of visiting the initial frontend in <from>.
+ *
+ * It is important to note that the function relies on the fact that all names
+ * have already been resolved.
+ */
+void propagate_processes(struct proxy *from, struct proxy *to)
+{
+ struct switching_rule *rule;
+ struct hdr_exp *exp;
+
+ if (to) {
+ /* check whether we need to go down */
+ if (from->bind_proc &&
+ (from->bind_proc & to->bind_proc) == from->bind_proc)
+ return;
+
+ if (!from->bind_proc && !to->bind_proc)
+ return;
+
+ to->bind_proc = from->bind_proc ?
+ (to->bind_proc | from->bind_proc) : 0;
+
+ /* now propagate down */
+ from = to;
+ }
+
+ if (!from->cap & PR_CAP_FE)
+ return;
+
+ /* default_backend */
+ if (from->defbe.be)
+ propagate_processes(from, from->defbe.be);
+
+ /* use_backend */
+ list_for_each_entry(rule, &from->switching_rules, list) {
+ if (rule->dynamic)
+ continue;
+ to = rule->be.backend;
+ propagate_processes(from, to);
+ }
+
+ /* reqsetbe */
+ for (exp = from->req_exp; exp != NULL; exp = exp->next) {
+ if (exp->action != ACT_SETBE)
+ continue;
+ to = (struct proxy *)exp->replace;
+ propagate_processes(from, to);
+ }
+}
+
/*
* Returns the error code, 0 if OK, or any combination of :
* - ERR_ABORT: must abort ASAP
@@ -5967,12 +6082,11 @@
proxy = next;
}
- while (curproxy != NULL) {
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
struct switching_rule *rule;
struct server_rule *srule;
struct sticking_rule *mrule;
struct tcp_rule *trule;
- struct listener *listener;
unsigned int next_id;
int nbproc;
@@ -6040,14 +6154,6 @@
}
}
- /* here, if bind_proc is null, it means no limit, otherwise it's explicit.
- * We now check how many processes the proxy will effectively run on.
- */
-
- nbproc = global.nbproc;
- if (curproxy->bind_proc)
- nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
-
if (global.nbproc > 1 && curproxy->table.peers.name) {
Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n",
curproxy->id);
@@ -6145,12 +6251,6 @@
} else {
free(curproxy->defbe.name);
curproxy->defbe.be = target;
- /* we force the backend to be present on at least all of
- * the frontend's processes.
- */
- if (target->bind_proc)
- target->bind_proc = curproxy->bind_proc ?
- (target->bind_proc | curproxy->bind_proc) : 0;
/* Emit a warning if this proxy also has some servers */
if (curproxy->srv) {
@@ -6183,12 +6283,6 @@
} else {
free((void *)exp->replace);
exp->replace = (const char *)target;
- /* we force the backend to be present on at least all of
- * the frontend's processes.
- */
- if (target->bind_proc)
- target->bind_proc = curproxy->bind_proc ?
- (target->bind_proc | curproxy->bind_proc) : 0;
}
}
}
@@ -6237,16 +6331,10 @@
} else {
free((void *)rule->be.name);
rule->be.backend = target;
- /* we force the backend to be present on at least all of
- * the frontend's processes.
- */
- if (target->bind_proc)
- target->bind_proc = curproxy->bind_proc ?
- (target->bind_proc | curproxy->bind_proc) : 0;
}
}
- /* find the target proxy for 'use_backend' rules */
+ /* find the target server for 'use_server' rules */
list_for_each_entry(srule, &curproxy->server_rules, list) {
struct server *target = findserver(curproxy, srule->srv.name);
@@ -6912,6 +7000,29 @@
newsrv = newsrv->next;
}
+ /* check if we have a frontend with "tcp-request content" looking at L7
+ * with no inspect-delay
+ */
+ if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
+ list_for_each_entry(trule, &curproxy->tcp_req.inspect_rules, list) {
+ if (trule->action == TCP_ACT_CAPTURE &&
+ !(trule->act_prm.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
+ break;
+ if ((trule->action >= TCP_ACT_TRK_SC0 && trule->action <= TCP_ACT_TRK_SCMAX) &&
+ !(trule->act_prm.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
+ break;
+ }
+
+ if (&trule->list != &curproxy->tcp_req.inspect_rules) {
+ Warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
+ " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
+ " This means that these rules will randomly find their contents. This can be fixed by"
+ " setting the tcp-request inspect-delay.\n",
+ proxy_type_str(curproxy), curproxy->id);
+ err_code |= ERR_WARN;
+ }
+ }
+
if (curproxy->cap & PR_CAP_FE) {
if (!curproxy->accept)
curproxy->accept = frontend_accept;
@@ -6948,6 +7059,90 @@
if (curproxy->options2 & PR_O2_RDPC_PRST)
curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
}
+ }
+
+ /***********************************************************/
+ /* At this point, target names have already been resolved. */
+ /***********************************************************/
+
+ /* Check multi-process mode compatibility */
+
+ if (global.nbproc > 1 && global.stats_fe) {
+ list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
+ unsigned long mask;
+
+ mask = nbits(global.nbproc);
+ if (global.stats_fe->bind_proc)
+ mask &= global.stats_fe->bind_proc;
+
+ if (bind_conf->bind_proc)
+ mask &= bind_conf->bind_proc;
+
+ /* stop here if more than one process is used */
+ if (popcount(mask) > 1)
+ break;
+ }
+ if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
+ Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
+ }
+ }
+
+ /* Make each frontend inherit bind-process from its listeners when not specified. */
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ if (curproxy->bind_proc)
+ continue;
+
+ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
+ unsigned long mask;
+
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
+ curproxy->bind_proc |= mask;
+ }
+
+ if (!curproxy->bind_proc)
+ curproxy->bind_proc = ~0UL;
+ }
+
+ if (global.stats_fe) {
+ list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
+ unsigned long mask;
+
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
+ global.stats_fe->bind_proc |= mask;
+ }
+ if (!global.stats_fe->bind_proc)
+ global.stats_fe->bind_proc = ~0UL;
+ }
+
+ /* propagate bindings from frontends to backends. Don't do it if there
+ * are any fatal errors as we must not call it with unresolved proxies.
+ */
+ if (!cfgerr) {
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ if (curproxy->cap & PR_CAP_FE)
+ propagate_processes(curproxy, NULL);
+ }
+ }
+
+ /* Bind each unbound backend to all processes when not specified. */
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ if (curproxy->bind_proc)
+ continue;
+ curproxy->bind_proc = ~0UL;
+ }
+
+ /*******************************************************/
+ /* At this step, all proxies have a non-null bind_proc */
+ /*******************************************************/
+
+ /* perform the final checks before creating tasks */
+
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ struct listener *listener;
+ unsigned int next_id;
+ int nbproc;
+
+ nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
#ifdef USE_OPENSSL
/* Configure SSL for each bind line.
@@ -7061,8 +7256,19 @@
if (nbproc > 1) {
if (curproxy->uri_auth) {
- Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n",
- curproxy->id);
+ int count, maxproc = 0;
+
+ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
+ count = popcount(bind_conf->bind_proc);
+ if (count > maxproc)
+ maxproc = count;
+ }
+ /* backends have 0, frontends have 1 or more */
+ if (maxproc != 1)
+ Warning("Proxy '%s': in multi-process mode, stats will be"
+ " limited to process assigned to the current request.\n",
+ curproxy->id);
+
if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
curproxy->id);
@@ -7092,29 +7298,6 @@
curproxy->id);
cfgerr++;
}
-
- curproxy = curproxy->next;
- }
-
- /* Check multi-process mode compatibility */
- if (global.nbproc > 1 && global.stats_fe) {
- list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
- unsigned long mask;
-
- mask = nbits(global.nbproc);
- if (global.stats_fe->bind_proc)
- mask &= global.stats_fe->bind_proc;
-
- if (bind_conf->bind_proc)
- mask &= bind_conf->bind_proc;
-
- /* stop here if more than one process is used */
- if (popcount(mask) > 1)
- break;
- }
- if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
- Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
- }
}
/* automatically compute fullconn if not set. We must not do it in the
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/checks.c
^
|
@@ -580,6 +580,7 @@
struct check *check = conn->owner;
const char *err_msg;
struct chunk *chk;
+ int step;
if (check->result != CHK_RES_UNKNOWN)
return;
@@ -599,19 +600,27 @@
chk = get_trash_chunk();
if (check->type == PR_O2_TCPCHK_CHK) {
- chunk_printf(chk, " at step %d of tcp-check", tcpcheck_get_step_id(check->server));
- /* we were looking for a string */
- if (check->current_step && check->current_step->action == TCPCHK_ACT_CONNECT) {
- chunk_appendf(chk, " (connect)");
- }
- else if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT) {
- if (check->current_step->string)
- chunk_appendf(chk, " (string '%s')", check->current_step->string);
- else if (check->current_step->expect_regex)
- chunk_appendf(chk, " (expect regex)");
- }
- else if (check->current_step && check->current_step->action == TCPCHK_ACT_SEND) {
- chunk_appendf(chk, " (send)");
+ step = tcpcheck_get_step_id(check->server);
+ if (!step)
+ chunk_printf(chk, " at initial connection step of tcp-check");
+ else {
+ chunk_printf(chk, " at step %d of tcp-check", step);
+ /* we were looking for a string */
+ if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_CONNECT) {
+ if (check->last_started_step->port)
+ chunk_appendf(chk, " (connect port %d)" ,check->last_started_step->port);
+ else
+ chunk_appendf(chk, " (connect)");
+ }
+ else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) {
+ if (check->last_started_step->string)
+ chunk_appendf(chk, " (string '%s')", check->last_started_step->string);
+ else if (check->last_started_step->expect_regex)
+ chunk_appendf(chk, " (expect regex)");
+ }
+ else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_SEND) {
+ chunk_appendf(chk, " (send)");
+ }
}
}
@@ -1818,6 +1827,10 @@
struct tcpcheck_rule *cur = NULL, *next = NULL;
int i = 0;
+ /* not even started anything yet => step 0 = initial connect */
+ if (!s->check.current_step)
+ return 0;
+
cur = s->check.last_started_step;
/* no step => first step */
@@ -1837,20 +1850,34 @@
static void tcpcheck_main(struct connection *conn)
{
char *contentptr;
- struct list *head = NULL;
struct tcpcheck_rule *cur = NULL;
int done = 0, ret = 0;
-
struct check *check = conn->owner;
struct server *s = check->server;
struct task *t = check->task;
+ struct list *head = &s->proxy->tcpcheck_rules;
- /*
- * don't do anything until the connection is established but if we're running
- * first step which must be a connect
+ /* here, we know that the check is complete or that it failed */
+ if (check->result != CHK_RES_UNKNOWN)
+ goto out_end_tcpcheck;
+
+ /* We have 4 possibilities here :
+ * 1. we've not yet attempted step 1, and step 1 is a connect, so no
+ * connection attempt was made yet ;
+ * 2. we've not yet attempted step 1, and step 1 is a not connect or
+ * does not exist (no rule), so a connection attempt was made
+ * before coming here.
+ * 3. we're coming back after having started with step 1, so we may
+ * be waiting for a connection attempt to complete.
+ * 4. the connection + handshake are complete
+ *
+ * #2 and #3 are quite similar, we want both the connection and the
+ * handshake to complete before going any further. Thus we must always
+ * wait for a connection to complete unless we're before and existing
+ * step 1.
*/
- if (check->current_step && (!(conn->flags & CO_FL_CONNECTED))) {
- /* update expire time, should be done by process_chk */
+ if ((!(conn->flags & CO_FL_CONNECTED) || (conn->flags & CO_FL_HANDSHAKE)) &&
+ (check->current_step || LIST_ISEMPTY(head))) {
/* we allow up to min(inter, timeout.connect) for a connection
* to establish but only when timeout.check is set
* as it may be to short for a full check otherwise
@@ -1867,16 +1894,15 @@
return;
}
- /* here, we know that the connection is established */
- if (check->result != CHK_RES_UNKNOWN)
+ /* special case: option tcp-check with no rule, a connect is enough */
+ if (LIST_ISEMPTY(head)) {
+ set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
goto out_end_tcpcheck;
+ }
- /* head is be the first element of the double chained list */
- head = &s->proxy->tcpcheck_rules;
-
- /* no step means first step
- * initialisation */
+ /* no step means first step initialisation */
if (check->current_step == NULL) {
+ check->last_started_step = NULL;
check->bo->p = check->bo->data;
check->bo->o = 0;
check->bi->p = check->bi->data;
@@ -1891,9 +1917,6 @@
cur = check->current_step;
}
- if (conn->flags & CO_FL_HANDSHAKE)
- return;
-
/* It's only the rules which will enable send/recv */
__conn_data_stop_both(conn);
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/connection.c
^
|
@@ -678,9 +678,11 @@
tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len-ret-ssl_tlv_len), PP2_TYPE_SSL_VERSION, strlen(value), value);
ssl_tlv_len += tlv_len;
}
- if (ssl_sock_get_cert_used(remote)) {
- tlv->client |= PP2_CLIENT_CERT;
+ if (ssl_sock_get_cert_used_sess(remote)) {
+ tlv->client |= PP2_CLIENT_CERT_SESS;
tlv->verify = htonl(ssl_sock_get_verify_result(remote));
+ if (ssl_sock_get_cert_used_conn(remote))
+ tlv->client |= PP2_CLIENT_CERT_CONN;
}
if (srv->pp_opts & SRV_PP_V2_SSL_CN) {
cn_trash = get_trash_chunk();
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/dumpstats.c
^
|
@@ -6045,7 +6045,7 @@
break;
case 1:
chunk_appendf(&trash,
- " backend %s (#%d) : invalid response\n"
+ " backend %s (#%d): invalid response\n"
" frontend %s (#%d)",
appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
es->oe->id, es->oe->uuid);
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/haproxy-systemd-wrapper.c
^
|
@@ -22,24 +22,42 @@
#define SD_DEBUG "<7>"
#define SD_NOTICE "<5>"
+static volatile sig_atomic_t caught_signal;
+
static char *pid_file = "/run/haproxy.pid";
static int wrapper_argc;
static char **wrapper_argv;
+/* returns the path to the haproxy binary into <buffer>, whose size indicated
+ * in <buffer_size> must be at least 1 byte long.
+ */
static void locate_haproxy(char *buffer, size_t buffer_size)
{
char *end = NULL;
+ int len;
- if (readlink("/proc/self/exe", buffer, buffer_size) > 0)
- end = strrchr(buffer, '/');
+ len = readlink("/proc/self/exe", buffer, buffer_size - 1);
+ if (len == -1)
+ goto fail;
+
+ buffer[len] = 0;
+ end = strrchr(buffer, '/');
+ if (end == NULL)
+ goto fail;
- if (end == NULL) {
- strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
+ if (strcmp(end + strlen(end) - 16, "-systemd-wrapper") == 0) {
+ end[strlen(end) - 16] = '\0';
return;
}
+
end[1] = '\0';
strncpy(end + 1, "haproxy", buffer + buffer_size - (end + 1));
buffer[buffer_size - 1] = '\0';
+ return;
+ fail:
+ strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
+ buffer[buffer_size - 1] = '\0';
+ return;
}
static void spawn_haproxy(char **pid_strv, int nb_pid)
@@ -103,7 +121,12 @@
return read;
}
-static void sigusr2_handler(int signum __attribute__((unused)))
+static void signal_handler(int signum)
+{
+ caught_signal = signum;
+}
+
+static void do_restart(void)
{
setenv(REEXEC_FLAG, "1", 1);
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing\n");
@@ -111,7 +134,7 @@
execv(wrapper_argv[0], wrapper_argv);
}
-static void sigint_handler(int signum __attribute__((unused)))
+static void do_shutdown(void)
{
int i, pid;
char **pid_strv = NULL;
@@ -130,11 +153,8 @@
static void init(int argc, char **argv)
{
while (argc > 1) {
- if (**argv == '-') {
- char *flag = *argv + 1;
- --argc; ++argv;
- if (*flag == 'p')
- pid_file = *argv;
+ if ((*argv)[0] == '-' && (*argv)[1] == 'p') {
+ pid_file = *(argv + 1);
}
--argc; ++argv;
}
@@ -150,25 +170,23 @@
--argc; ++argv;
init(argc, argv);
- signal(SIGINT, &sigint_handler);
- signal(SIGUSR2, &sigusr2_handler);
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = &signal_handler;
+ sigaction(SIGUSR2, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
if (getenv(REEXEC_FLAG) != NULL) {
/* We are being re-executed: restart HAProxy gracefully */
int i;
char **pid_strv = NULL;
int nb_pid = read_pids(&pid_strv);
- sigset_t sigs;
unsetenv(REEXEC_FLAG);
spawn_haproxy(pid_strv, nb_pid);
- /* Unblock SIGUSR2 which was blocked by the signal handler
- * before re-exec */
- sigprocmask(SIG_BLOCK, NULL, &sigs);
- sigdelset(&sigs, SIGUSR2);
- sigprocmask(SIG_SETMASK, &sigs, NULL);
-
for (i = 0; i < nb_pid; ++i)
free(pid_strv[i]);
free(pid_strv);
@@ -179,8 +197,16 @@
}
status = -1;
- while (-1 != wait(&status) || errno == EINTR)
- ;
+ while (-1 != wait(&status) || errno == EINTR) {
+ if (caught_signal == SIGUSR2 || caught_signal == SIGHUP) {
+ caught_signal = 0;
+ do_restart();
+ }
+ else if (caught_signal == SIGINT || caught_signal == SIGTERM) {
+ caught_signal = 0;
+ do_shutdown();
+ }
+ }
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n",
status);
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/pattern.c
^
|
@@ -178,19 +178,15 @@
*
* These functions are exported and may be used by any other component.
*
- * The following functions are used for parsing pattern matching
- * input value. The <text> contain the string to be parsed. <pattern>
- * must be a preallocated pattern. The pat_parse_* functions fill this
- * structure with the parsed value. <usage> can be PAT_U_COMPILE or
- * PAT_U_LOOKUP. If the value PAT_U_COMPILE is used memory is allocated
- * for filling the pattern. If the value PAT_U_LOOKUP is set, the parser
- * use "trash" or return pointers to the input strings. In both cases,
- * the caller must use the value PAT_U_LOOKUP with caution. <err> is
- * filled with an error message built with memprintf() function.
- *
- * In succes case, the pat_parse_* function return 1. If the function
- * fail, it returns 0 and <err> is filled.
+ * The following functions are used for parsing pattern matching input value.
+ * The <text> contain the string to be parsed. <pattern> must be a preallocated
+ * pattern. The pat_parse_* functions fill this structure with the parsed value.
+ * <err> is filled with an error message built with memprintf() function. It is
+ * allowed to use a trash as a temporary storage for the returned pattern, as
+ * the next call after these functions will be pat_idx_*.
*
+ * In success case, the pat_parse_* function returns 1. If the function
+ * fails, it returns 0 and <err> is filled.
*/
/* ignore the current line */
@@ -223,17 +219,7 @@
/* Parse a regex. It is allocated. */
int pat_parse_reg(const char *text, struct pattern *pattern, int mflags, char **err)
{
- struct chunk *trash;
-
- trash = get_trash_chunk();
- if (trash->size < sizeof(*pattern->ptr.reg)) {
- memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
- (int)sizeof(*pattern->ptr.reg), trash->size);
- return 0;
- }
-
pattern->ptr.str = (char *)text;
-
return 1;
}
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/proto_http.c
^
|
@@ -2393,6 +2393,59 @@
return 0;
}
+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg)
+{
+ int tmp = TX_CON_WANT_KAL;
+
+ if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) {
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN ||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
+ tmp = TX_CON_WANT_TUN;
+
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
+ tmp = TX_CON_WANT_TUN;
+ }
+
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL ||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) {
+ /* option httpclose + server_close => forceclose */
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
+ tmp = TX_CON_WANT_CLO;
+ else
+ tmp = TX_CON_WANT_SCL;
+ }
+
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL ||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
+ tmp = TX_CON_WANT_CLO;
+
+ if ((txn->flags & TX_CON_WANT_MSK) < tmp)
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
+
+ if (!(txn->flags & TX_HDR_CONN_PRS) &&
+ (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) {
+ /* parse the Connection header and possibly clean it */
+ int to_del = 0;
+ if ((msg->flags & HTTP_MSGF_VER_11) ||
+ ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL &&
+ !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)))
+ to_del |= 2; /* remove "keep-alive" */
+ if (!(msg->flags & HTTP_MSGF_VER_11))
+ to_del |= 1; /* remove "close" */
+ http_parse_connection_header(txn, msg, to_del);
+ }
+
+ /* check if client or config asks for explicit close in KAL/SCL */
+ if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
+ (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) &&
+ ((txn->flags & TX_HDR_CONN_CLO) || /* "connection: close" */
+ (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */
+ !(msg->flags & HTTP_MSGF_XFER_LEN) || /* no length known => close */
+ s->fe->state == PR_STSTOPPED)) /* frontend is stopping */
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+}
/* This stream analyser waits for a complete HTTP request. It returns 1 if the
* processing can continue on next analysers, or zero if it either needs more
@@ -2929,58 +2982,8 @@
* time.
*/
if (!(txn->flags & TX_HDR_CONN_PRS) ||
- ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE))) {
- int tmp = TX_CON_WANT_KAL;
-
- if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) {
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
- tmp = TX_CON_WANT_TUN;
-
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
- tmp = TX_CON_WANT_TUN;
- }
-
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) {
- /* option httpclose + server_close => forceclose */
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
- tmp = TX_CON_WANT_CLO;
- else
- tmp = TX_CON_WANT_SCL;
- }
-
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
- tmp = TX_CON_WANT_CLO;
-
- if ((txn->flags & TX_CON_WANT_MSK) < tmp)
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
-
- if (!(txn->flags & TX_HDR_CONN_PRS) &&
- (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) {
- /* parse the Connection header and possibly clean it */
- int to_del = 0;
- if ((msg->flags & HTTP_MSGF_VER_11) ||
- ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL &&
- !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)))
- to_del |= 2; /* remove "keep-alive" */
- if (!(msg->flags & HTTP_MSGF_VER_11))
- to_del |= 1; /* remove "close" */
- http_parse_connection_header(txn, msg, to_del);
- }
-
- /* check if client or config asks for explicit close in KAL/SCL */
- if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
- (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) &&
- ((txn->flags & TX_HDR_CONN_CLO) || /* "connection: close" */
- (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */
- !(msg->flags & HTTP_MSGF_XFER_LEN) || /* no length known => close */
- s->fe->state == PR_STSTOPPED)) /* frontend is stopping */
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
- }
+ ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE)))
+ http_adjust_conn_mode(s, txn, msg);
/* end of job, return OK */
req->analysers &= ~an_bit;
@@ -4117,8 +4120,9 @@
done: /* done with this analyser, continue with next ones that the calling
* points will have set, if any.
*/
- req->analysers &= ~an_bit;
req->analyse_exp = TICK_ETERNITY;
+ done_without_exp: /* done with this analyser, but dont reset the analyse_exp. */
+ req->analysers &= ~an_bit;
return 1;
tarpit:
@@ -4144,7 +4148,7 @@
s->be->be_counters.denied_req++;
if (s->listener->counters)
s->listener->counters->denied_req++;
- goto done;
+ goto done_without_exp;
deny: /* this request was blocked (denied) */
txn->flags |= TX_CLDENY;
@@ -4885,8 +4889,8 @@
s->req->cons->conn_retries = 0; /* used for logging too */
s->req->cons->exp = TICK_ETERNITY;
s->req->cons->flags &= SI_FL_DONT_WAKE; /* we're in the context of process_session */
- s->req->flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT);
- s->rep->flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT);
+ s->req->flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT|CF_WROTE_DATA);
+ s->rep->flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA);
s->flags &= ~(SN_DIRECT|SN_ASSIGNED|SN_ADDR_SET|SN_BE_ASSIGNED|SN_FORCE_PRST|SN_IGNORE_PRST);
s->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE|SN_SRV_REUSED);
@@ -5429,7 +5433,7 @@
* such as last chunk of data or trailers.
*/
b_adv(req->buf, msg->next);
- if (unlikely(!(s->rep->flags & CF_READ_ATTACHED)))
+ if (unlikely(!(s->req->flags & CF_WROTE_DATA)))
msg->sov -= msg->next;
msg->next = 0;
@@ -5481,7 +5485,7 @@
missing_data:
/* we may have some pending data starting at req->buf->p */
b_adv(req->buf, msg->next);
- if (unlikely(!(s->rep->flags & CF_READ_ATTACHED)))
+ if (unlikely(!(s->req->flags & CF_WROTE_DATA)))
msg->sov -= msg->next + MIN(msg->chunk_len, req->buf->i);
msg->next = 0;
@@ -6248,7 +6252,7 @@
/* add response headers from the rule sets in the same order */
list_for_each_entry(wl, &rule_set->rsp_add, list) {
- if (txn->status < 200)
+ if (txn->status < 200 && txn->status != 101)
break;
if (wl->cond) {
int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
@@ -6269,7 +6273,7 @@
}
/* OK that's all we can do for 1xx responses */
- if (unlikely(txn->status < 200))
+ if (unlikely(txn->status < 200 && txn->status != 101))
goto skip_header_mangling;
/*
@@ -6282,7 +6286,7 @@
/*
* Check for cache-control or pragma headers if required.
*/
- if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
+ if (((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC)) && txn->status != 101)
check_response_for_cacheability(s, rep);
/*
@@ -6398,9 +6402,11 @@
* Adjust "Connection: close" or "Connection: keep-alive" if needed.
* If an "Upgrade" token is found, the header is left untouched in order
* not to have to deal with some client bugs : some of them fail an upgrade
- * if anything but "Upgrade" is present in the Connection header.
+ * if anything but "Upgrade" is present in the Connection header. We don't
+ * want to touch any 101 response either since it's switching to another
+ * protocol.
*/
- if (!(txn->flags & TX_HDR_CONN_UPG) &&
+ if ((txn->status != 101) && !(txn->flags & TX_HDR_CONN_UPG) &&
(((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
(s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
@@ -9281,8 +9287,8 @@
cur_arg = 1;
if (!*args[cur_arg] || !*args[cur_arg+1] || !*args[cur_arg+2] ||
- (*args[cur_arg+3] && strcmp(args[cur_arg+2], "if") != 0 && strcmp(args[cur_arg+2], "unless") != 0)) {
- Alert("parsing [%s:%d]: 'http-request %s' expects exactly 3 arguments.\n",
+ (*args[cur_arg+3] && strcmp(args[cur_arg+3], "if") != 0 && strcmp(args[cur_arg+3], "unless") != 0)) {
+ Alert("parsing [%s:%d]: 'http-response %s' expects exactly 3 arguments.\n",
file, linenum, args[0]);
goto out_err;
}
@@ -9770,20 +9776,13 @@
static int pat_parse_meth(const char *text, struct pattern *pattern, int mflags, char **err)
{
int len, meth;
- struct chunk *trash;
len = strlen(text);
meth = find_http_meth(text, len);
pattern->val.i = meth;
if (meth == HTTP_METH_OTHER) {
- trash = get_trash_chunk();
- if (trash->size < len) {
- memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
- len, trash->size);
- return 0;
- }
- pattern->ptr.str = trash->str;
+ pattern->ptr.str = (char *)text;
pattern->len = len;
}
else {
@@ -9848,8 +9847,8 @@
continue;
icase = expr->mflags & PAT_MF_IGNORE_CASE;
- if ((icase && strncasecmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) != 0) ||
- (!icase && strncmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) != 0))
+ if ((icase && strncasecmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) == 0) ||
+ (!icase && strncmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) == 0))
return pattern;
}
return NULL;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/proto_tcp.c
^
|
@@ -1048,8 +1048,8 @@
t = rule->act_prm.trk_ctr.table.t;
key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.trk_ctr.expr, &smp);
- if (smp.flags & SMP_F_MAY_CHANGE)
- goto missing_data;
+ if ((smp.flags & SMP_F_MAY_CHANGE) && !(partial & SMP_OPT_FINAL))
+ goto missing_data; /* key might appear later */
if (key && (ts = stktable_get_entry(t, key))) {
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
@@ -1711,6 +1711,8 @@
warn++;
}
+ /* the following function directly emits the warning */
+ warnif_misplaced_tcp_cont(curpx, file, line, args[0]);
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
}
else if (strcmp(args[1], "connection") == 0) {
@@ -1754,6 +1756,8 @@
warn++;
}
+ /* the following function directly emits the warning */
+ warnif_misplaced_tcp_conn(curpx, file, line, args[0]);
LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list);
}
else {
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/proxy.c
^
|
@@ -955,6 +955,14 @@
http_init_txn(s);
}
+ /* If we chain to an HTTP backend running a different HTTP mode, we
+ * have to re-adjust the desired keep-alive/close mode to accommodate
+ * both the frontend's and the backend's modes.
+ */
+ if (s->fe->mode == PR_MODE_HTTP && be->mode == PR_MODE_HTTP &&
+ ((s->fe->options & PR_O_HTTP_MODE) != (be->options & PR_O_HTTP_MODE)))
+ http_adjust_conn_mode(s, &s->txn, &s->txn.req);
+
/* If an LB algorithm needs to access some pre-parsed body contents,
* we must not start to forward anything until the connection is
* confirmed otherwise we'll lose the pointer to these data and
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/sample.c
^
|
@@ -896,6 +896,18 @@
* Note: the fetch functions are required to properly set the return type. The
* conversion functions must do so too. However the cast functions do not need
* to since they're made to cast mutiple types according to what is required.
+ *
+ * The caller may indicate in <opt> if it considers the result final or not.
+ * The caller needs to check the SMP_F_MAY_CHANGE flag in p->flags to verify
+ * if the result is stable or not, according to the following table :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL 0 * Not present and will never be (eg: header)
+ * NULL 1 0 Not present yet, could change (eg: POST param)
+ * NULL 1 1 Not present yet, will not change anymore
+ * smp 0 * Present and will not change (eg: header)
+ * smp 1 0 Present, may change (eg: request length)
+ * smp 1 1 Present, last known value (eg: request length)
*/
struct sample *sample_process(struct proxy *px, struct session *l4, void *l7,
unsigned int opt,
@@ -1153,7 +1165,16 @@
* and <opt> does not contain SMP_OPT_FINAL, then the sample is returned as-is
* with its SMP_F_MAY_CHANGE flag so that the caller can check it and decide to
* take actions (eg: wait longer). If a sample could not be found or could not
- * be converted, NULL is returned.
+ * be converted, NULL is returned. The caller MUST NOT use the sample if the
+ * SMP_F_MAY_CHANGE flag is present, as it is used only as a hint that there is
+ * still hope to get it after waiting longer, and is not converted to string.
+ * The possible output combinations are the following :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL * * Not present and will never be (eg: header)
+ * smp 0 * Final value converted (eg: header)
+ * smp 1 0 Not present yet, may appear later (eg: header)
+ * smp 1 1 never happens (either flag is cleared on output)
*/
struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l7,
unsigned int opt, struct sample_expr *expr)
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/ssl_sock.c
^
|
@@ -2720,8 +2720,25 @@
return result;
}
-/* returns 1 if client passed a certificate, 0 if not */
-int ssl_sock_get_cert_used(struct connection *conn)
+/* returns 1 if client passed a certificate for this session, 0 if not */
+int ssl_sock_get_cert_used_sess(struct connection *conn)
+{
+ X509 *crt = NULL;
+
+ if (!ssl_sock_is_ssl(conn))
+ return 0;
+
+ /* SSL_get_peer_certificate, it increase X509 * ref count */
+ crt = SSL_get_peer_certificate(conn->xprt_ctx);
+ if (!crt)
+ return 0;
+
+ X509_free(crt);
+ return 1;
+}
+
+/* returns 1 if client passed a certificate for this connection, 0 if not */
+int ssl_sock_get_cert_used_conn(struct connection *conn)
{
if (!ssl_sock_is_ssl(conn))
return 0;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/stick_table.c
^
|
@@ -603,7 +603,16 @@
* no key could be extracted, or a pointer to the converted result stored in
* static_table_key in format <table_type>. If <smp> is not NULL, it will be reset
* and its flags will be initialized so that the caller gets a copy of the input
- * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present).
+ * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present
+ * without SMP_OPT_FINAL). The output will be usable like this :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL 0 * Not present and will never be (eg: header)
+ * NULL 1 0 Not present or unstable, could change (eg: req_len)
+ * NULL 1 1 Not present, will not change anymore
+ * smp 0 * Present and will not change (eg: header)
+ * smp 1 0 not possible
+ * smp 1 1 Present, last known value (eg: request length)
*/
struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *l4, void *l7,
unsigned int opt, struct sample_expr *expr, struct sample *smp)
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.5.tar.gz/src/stream_interface.c
^
|
@@ -658,7 +658,7 @@
if (chn->pipe && conn->xprt->snd_pipe) {
ret = conn->xprt->snd_pipe(conn, chn->pipe);
if (ret > 0)
- chn->flags |= CF_WRITE_PARTIAL;
+ chn->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
if (!chn->pipe->data) {
put_pipe(chn->pipe);
@@ -702,7 +702,7 @@
ret = conn->xprt->snd_buf(conn, chn->buf, send_flag);
if (ret > 0) {
- chn->flags |= CF_WRITE_PARTIAL;
+ chn->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
if (!chn->buf->o) {
/* Always clear both flags once everything has been sent, they're one-shot */
|