|
@@ -1,111 +0,0 @@
|
1
|
|
-From f94735eb76e634d7531f9c903113f64820c4cec0 Mon Sep 17 00:00:00 2001
|
2
|
|
-From: Willy Tarreau <w@1wt.eu>
|
3
|
|
-Date: Wed, 30 Jul 2014 08:56:35 +0200
|
4
|
|
-Subject: [PATCH 3/3] BUG/MAJOR: tcp: fix a possible busy spinning loop in
|
5
|
|
- content track-sc*
|
6
|
|
-
|
7
|
|
-As a consequence of various recent changes on the sample conversion,
|
8
|
|
-a corner case has emerged where it is possible to wait forever for a
|
9
|
|
-sample in track-sc*.
|
10
|
|
-
|
11
|
|
-The issue is caused by the fact that functions relying on sample_process()
|
12
|
|
-don't all exactly work the same regarding the SMP_F_MAY_CHANGE flag and
|
13
|
|
-the output result. Here it was possible to wait forever for an output
|
14
|
|
-sample from stktable_fetch_key() without checking the SMP_OPT_FINAL flag.
|
15
|
|
-As a result, if the client connects and closes without sending the data
|
16
|
|
-and haproxy expects a sample which is capable of coming, it will ignore
|
17
|
|
-this impossible case and will continue to wait.
|
18
|
|
-
|
19
|
|
-This change adds control for SMP_OPT_FINAL before waiting for extra data.
|
20
|
|
-The various relevant functions have been better documented regarding their
|
21
|
|
-output values.
|
22
|
|
-
|
23
|
|
-This fix must be backported to 1.5 since it appeared there.
|
24
|
|
-(cherry picked from commit 6bcb0a84e7256f00793fa8ec8a0d6c19c3b22935)
|
25
|
|
----
|
26
|
|
- src/proto_tcp.c | 4 ++--
|
27
|
|
- src/sample.c | 23 ++++++++++++++++++++++-
|
28
|
|
- src/stick_table.c | 11 ++++++++++-
|
29
|
|
- 3 files changed, 34 insertions(+), 4 deletions(-)
|
30
|
|
-
|
31
|
|
-diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
32
|
|
-index 9778856..72dc92b 100644
|
33
|
|
---- a/src/proto_tcp.c
|
34
|
|
-+++ b/src/proto_tcp.c
|
35
|
|
-@@ -1048,8 +1048,8 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
|
36
|
|
- t = rule->act_prm.trk_ctr.table.t;
|
37
|
|
- key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.trk_ctr.expr, &smp);
|
38
|
|
-
|
39
|
|
-- if (smp.flags & SMP_F_MAY_CHANGE)
|
40
|
|
-- goto missing_data;
|
41
|
|
-+ if ((smp.flags & SMP_F_MAY_CHANGE) && !(partial & SMP_OPT_FINAL))
|
42
|
|
-+ goto missing_data; /* key might appear later */
|
43
|
|
-
|
44
|
|
- if (key && (ts = stktable_get_entry(t, key))) {
|
45
|
|
- session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
|
46
|
|
-diff --git a/src/sample.c b/src/sample.c
|
47
|
|
-index 3a0f3fb..8e62640 100644
|
48
|
|
---- a/src/sample.c
|
49
|
|
-+++ b/src/sample.c
|
50
|
|
-@@ -896,6 +896,18 @@ out_error:
|
51
|
|
- * Note: the fetch functions are required to properly set the return type. The
|
52
|
|
- * conversion functions must do so too. However the cast functions do not need
|
53
|
|
- * to since they're made to cast mutiple types according to what is required.
|
54
|
|
-+ *
|
55
|
|
-+ * The caller may indicate in <opt> if it considers the result final or not.
|
56
|
|
-+ * The caller needs to check the SMP_F_MAY_CHANGE flag in p->flags to verify
|
57
|
|
-+ * if the result is stable or not, according to the following table :
|
58
|
|
-+ *
|
59
|
|
-+ * return MAY_CHANGE FINAL Meaning for the sample
|
60
|
|
-+ * NULL 0 * Not present and will never be (eg: header)
|
61
|
|
-+ * NULL 1 0 Not present yet, could change (eg: POST param)
|
62
|
|
-+ * NULL 1 1 Not present yet, will not change anymore
|
63
|
|
-+ * smp 0 * Present and will not change (eg: header)
|
64
|
|
-+ * smp 1 0 Present, may change (eg: request length)
|
65
|
|
-+ * smp 1 1 Present, last known value (eg: request length)
|
66
|
|
- */
|
67
|
|
- struct sample *sample_process(struct proxy *px, struct session *l4, void *l7,
|
68
|
|
- unsigned int opt,
|
69
|
|
-@@ -1153,7 +1165,16 @@ int smp_resolve_args(struct proxy *p)
|
70
|
|
- * and <opt> does not contain SMP_OPT_FINAL, then the sample is returned as-is
|
71
|
|
- * with its SMP_F_MAY_CHANGE flag so that the caller can check it and decide to
|
72
|
|
- * take actions (eg: wait longer). If a sample could not be found or could not
|
73
|
|
-- * be converted, NULL is returned.
|
74
|
|
-+ * be converted, NULL is returned. The caller MUST NOT use the sample if the
|
75
|
|
-+ * SMP_F_MAY_CHANGE flag is present, as it is used only as a hint that there is
|
76
|
|
-+ * still hope to get it after waiting longer, and is not converted to string.
|
77
|
|
-+ * The possible output combinations are the following :
|
78
|
|
-+ *
|
79
|
|
-+ * return MAY_CHANGE FINAL Meaning for the sample
|
80
|
|
-+ * NULL * * Not present and will never be (eg: header)
|
81
|
|
-+ * smp 0 * Final value converted (eg: header)
|
82
|
|
-+ * smp 1 0 Not present yet, may appear later (eg: header)
|
83
|
|
-+ * smp 1 1 never happens (either flag is cleared on output)
|
84
|
|
- */
|
85
|
|
- struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l7,
|
86
|
|
- unsigned int opt, struct sample_expr *expr)
|
87
|
|
-diff --git a/src/stick_table.c b/src/stick_table.c
|
88
|
|
-index a708d3c..d39b4ff 100644
|
89
|
|
---- a/src/stick_table.c
|
90
|
|
-+++ b/src/stick_table.c
|
91
|
|
-@@ -603,7 +603,16 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
|
92
|
|
- * no key could be extracted, or a pointer to the converted result stored in
|
93
|
|
- * static_table_key in format <table_type>. If <smp> is not NULL, it will be reset
|
94
|
|
- * and its flags will be initialized so that the caller gets a copy of the input
|
95
|
|
-- * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present).
|
96
|
|
-+ * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present
|
97
|
|
-+ * without SMP_OPT_FINAL). The output will be usable like this :
|
98
|
|
-+ *
|
99
|
|
-+ * return MAY_CHANGE FINAL Meaning for the sample
|
100
|
|
-+ * NULL 0 * Not present and will never be (eg: header)
|
101
|
|
-+ * NULL 1 0 Not present or unstable, could change (eg: req_len)
|
102
|
|
-+ * NULL 1 1 Not present, will not change anymore
|
103
|
|
-+ * smp 0 * Present and will not change (eg: header)
|
104
|
|
-+ * smp 1 0 not possible
|
105
|
|
-+ * smp 1 1 Present, last known value (eg: request length)
|
106
|
|
- */
|
107
|
|
- struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *l4, void *l7,
|
108
|
|
- unsigned int opt, struct sample_expr *expr, struct sample *smp)
|
109
|
|
-1.8.5.5
|
110
|
|
-
|