|
@@ -1,506 +0,0 @@
|
1
|
|
-From af2038557a14bf6e2915bed545e216a0f1a95fc5 Mon Sep 17 00:00:00 2001
|
2
|
|
-From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
|
3
|
|
-Date: Mon, 15 Apr 2013 22:05:00 +0200
|
4
|
|
-Subject: [PATCH] Proxy Protocol based on haproxy 1.4.23
|
5
|
|
-
|
6
|
|
----
|
7
|
|
- doc/configuration.txt | 26 ++++++-
|
8
|
|
- include/common/standard.h | 25 ++++++-
|
9
|
|
- include/proto/client.h | 1 +
|
10
|
|
- include/types/buffers.h | 20 ++---
|
11
|
|
- include/types/protocols.h | 1 +
|
12
|
|
- src/cfgparse.c | 15 +++-
|
13
|
|
- src/client.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++
|
14
|
|
- src/proto_http.c | 4 +-
|
15
|
|
- src/session.c | 7 ++
|
16
|
|
- src/standard.c | 9 ++-
|
17
|
|
- 10 files changed, 275 insertions(+), 19 deletions(-)
|
18
|
|
-
|
19
|
|
-Index: haproxy-1.4.25/doc/configuration.txt
|
20
|
|
-===================================================================
|
21
|
|
---- haproxy-1.4.25.orig/doc/configuration.txt
|
22
|
|
-+++ haproxy-1.4.25/doc/configuration.txt
|
23
|
|
-@@ -1343,6 +1343,7 @@ bind [<address>]:<port_range> [, ...] tr
|
24
|
|
- bind [<address>]:<port_range> [, ...] id <id>
|
25
|
|
- bind [<address>]:<port_range> [, ...] name <name>
|
26
|
|
- bind [<address>]:<port_range> [, ...] defer-accept
|
27
|
|
-+bind [<address>]:<port_range> [, ...] accept-proxy
|
28
|
|
- Define one or several listening addresses and/or ports in a frontend.
|
29
|
|
- May be used in sections : defaults | frontend | listen | backend
|
30
|
|
- no | yes | yes | no
|
31
|
|
-@@ -1423,6 +1424,19 @@ bind [<address>]:<port_range> [, ...] de
|
32
|
|
- with front firewalls which would see an established
|
33
|
|
- connection while the proxy will only see it in SYN_RECV.
|
34
|
|
-
|
35
|
|
-+ accept-proxy is an optional keyword which enforces use of the PROXY
|
36
|
|
-+ protocol over any connection accepted by this listener. The
|
37
|
|
-+ PROXY protocol dictates the layer 3/4 addresses of the
|
38
|
|
-+ incoming connection to be used everywhere an address is used,
|
39
|
|
-+ with the only exception of "tcp-request connection" rules
|
40
|
|
-+ which will only see the real connection address. Logs will
|
41
|
|
-+ reflect the addresses indicated in the protocol, unless it is
|
42
|
|
-+ violated, in which case the real address will still be used.
|
43
|
|
-+ This keyword combined with support from external components
|
44
|
|
-+ can be used as an efficient and reliable alternative to the
|
45
|
|
-+ X-Forwarded-For mechanism which is not always reliable and
|
46
|
|
-+ not even always usable.
|
47
|
|
-+
|
48
|
|
- It is possible to specify a list of address:port combinations delimited by
|
49
|
|
- commas. The frontend will then listen on all of these addresses. There is no
|
50
|
|
- fixed limit to the number of addresses and ports which can be listened on in
|
51
|
|
-@@ -1433,8 +1447,10 @@ bind [<address>]:<port_range> [, ...] de
|
52
|
|
- listen http_proxy
|
53
|
|
- bind :80,:443
|
54
|
|
- bind 10.0.0.1:10080,10.0.0.1:10443
|
55
|
|
-+ bind 127.0.0.1:8443 accept-proxy
|
56
|
|
-
|
57
|
|
-- See also : "source".
|
58
|
|
-+ See also : "source", "option forwardfor" and the PROXY protocol
|
59
|
|
-+ documentation.
|
60
|
|
-
|
61
|
|
-
|
62
|
|
- bind-process [ all | odd | even | <number 1-32> ] ...
|
63
|
|
-@@ -7257,7 +7273,9 @@ marked with a star ('*') after the field
|
64
|
|
-
|
65
|
|
- Detailed fields description :
|
66
|
|
- - "client_ip" is the IP address of the client which initiated the TCP
|
67
|
|
-- connection to haproxy.
|
68
|
|
-+ connection to haproxy. Note that when the connection is accepted on a
|
69
|
|
-+ socket configured with "accept-proxy" and the PROXY protocol is correctly
|
70
|
|
-+ used, then the logs will reflect the forwarded connection's information.
|
71
|
|
-
|
72
|
|
- - "client_port" is the TCP port of the client which initiated the connection.
|
73
|
|
-
|
74
|
|
-@@ -7430,7 +7448,9 @@ with a star ('*') after the field name b
|
75
|
|
-
|
76
|
|
- Detailed fields description :
|
77
|
|
- - "client_ip" is the IP address of the client which initiated the TCP
|
78
|
|
-- connection to haproxy.
|
79
|
|
-+ connection to haproxy. Note that when the connection is accepted on a
|
80
|
|
-+ socket configured with "accept-proxy" and the PROXY protocol is correctly
|
81
|
|
-+ used, then the logs will reflect the forwarded connection's information.
|
82
|
|
-
|
83
|
|
- - "client_port" is the TCP port of the client which initiated the connection.
|
84
|
|
-
|
85
|
|
-Index: haproxy-1.4.25/include/common/standard.h
|
86
|
|
-===================================================================
|
87
|
|
---- haproxy-1.4.25.orig/include/common/standard.h
|
88
|
|
-+++ haproxy-1.4.25/include/common/standard.h
|
89
|
|
-@@ -269,6 +269,28 @@ static inline unsigned int __strl2uic(co
|
90
|
|
- return i;
|
91
|
|
- }
|
92
|
|
-
|
93
|
|
-+/* This function reads an unsigned integer from the string pointed to by <s>
|
94
|
|
-+ * and returns it. The <s> pointer is adjusted to point to the first unread
|
95
|
|
-+ * char. The function automatically stops at <end>.
|
96
|
|
-+ */
|
97
|
|
-+static inline unsigned int __read_uint(const char **s, const char *end)
|
98
|
|
-+{
|
99
|
|
-+ const char *ptr = *s;
|
100
|
|
-+ unsigned int i = 0;
|
101
|
|
-+ unsigned int j, k;
|
102
|
|
-+
|
103
|
|
-+ while (ptr < end) {
|
104
|
|
-+ j = *ptr - '0';
|
105
|
|
-+ k = i * 10;
|
106
|
|
-+ if (j > 9)
|
107
|
|
-+ break;
|
108
|
|
-+ i = k + j;
|
109
|
|
-+ ptr++;
|
110
|
|
-+ }
|
111
|
|
-+ *s = ptr;
|
112
|
|
-+ return i;
|
113
|
|
-+}
|
114
|
|
-+
|
115
|
|
- extern unsigned int str2ui(const char *s);
|
116
|
|
- extern unsigned int str2uic(const char *s);
|
117
|
|
- extern unsigned int strl2ui(const char *s, int len);
|
118
|
|
-@@ -276,9 +298,10 @@ extern unsigned int strl2uic(const char
|
119
|
|
- extern int strl2ic(const char *s, int len);
|
120
|
|
- extern int strl2irc(const char *s, int len, int *ret);
|
121
|
|
- extern int strl2llrc(const char *s, int len, long long *ret);
|
122
|
|
-+extern unsigned int read_uint(const char **s, const char *end);
|
123
|
|
- unsigned int inetaddr_host(const char *text);
|
124
|
|
- unsigned int inetaddr_host_lim(const char *text, const char *stop);
|
125
|
|
--unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret);
|
126
|
|
-+unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret);
|
127
|
|
-
|
128
|
|
- static inline char *cut_crlf(char *s) {
|
129
|
|
-
|
130
|
|
-Index: haproxy-1.4.25/include/proto/client.h
|
131
|
|
-===================================================================
|
132
|
|
---- haproxy-1.4.25.orig/include/proto/client.h
|
133
|
|
-+++ haproxy-1.4.25/include/proto/client.h
|
134
|
|
-@@ -25,6 +25,7 @@
|
135
|
|
- #include <common/config.h>
|
136
|
|
- #include <types/session.h>
|
137
|
|
-
|
138
|
|
-+int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit);
|
139
|
|
- void get_frt_addr(struct session *s);
|
140
|
|
- int event_accept(int fd);
|
141
|
|
-
|
142
|
|
-Index: haproxy-1.4.25/include/types/buffers.h
|
143
|
|
-===================================================================
|
144
|
|
---- haproxy-1.4.25.orig/include/types/buffers.h
|
145
|
|
-+++ haproxy-1.4.25/include/types/buffers.h
|
146
|
|
-@@ -135,16 +135,16 @@
|
147
|
|
- * The field is blanked by buffer_init() and only by analysers themselves
|
148
|
|
- * afterwards.
|
149
|
|
- */
|
150
|
|
--#define AN_REQ_INSPECT 0x00000001 /* inspect request contents */
|
151
|
|
--#define AN_REQ_WAIT_HTTP 0x00000002 /* wait for an HTTP request */
|
152
|
|
--#define AN_REQ_HTTP_PROCESS_FE 0x00000004 /* process the frontend's HTTP part */
|
153
|
|
--#define AN_REQ_SWITCHING_RULES 0x00000008 /* apply the switching rules */
|
154
|
|
--#define AN_REQ_HTTP_PROCESS_BE 0x00000010 /* process the backend's HTTP part */
|
155
|
|
--#define AN_REQ_HTTP_INNER 0x00000020 /* inner processing of HTTP request */
|
156
|
|
--#define AN_REQ_HTTP_TARPIT 0x00000040 /* wait for end of HTTP tarpit */
|
157
|
|
--#define AN_REQ_HTTP_BODY 0x00000080 /* inspect HTTP request body */
|
158
|
|
--#define AN_REQ_STICKING_RULES 0x00000100 /* table persistence matching */
|
159
|
|
--/* unused: 0x200 */
|
160
|
|
-+#define AN_REQ_DECODE_PROXY 0x00000001 /* take the proxied address from a 'PROXY' line */
|
161
|
|
-+#define AN_REQ_INSPECT 0x00000002 /* inspect request contents */
|
162
|
|
-+#define AN_REQ_WAIT_HTTP 0x00000004 /* wait for an HTTP request */
|
163
|
|
-+#define AN_REQ_HTTP_PROCESS_FE 0x00000008 /* process the frontend's HTTP part */
|
164
|
|
-+#define AN_REQ_SWITCHING_RULES 0x00000010 /* apply the switching rules */
|
165
|
|
-+#define AN_REQ_HTTP_PROCESS_BE 0x00000020 /* process the backend's HTTP part */
|
166
|
|
-+#define AN_REQ_HTTP_INNER 0x00000040 /* inner processing of HTTP request */
|
167
|
|
-+#define AN_REQ_HTTP_TARPIT 0x00000080 /* wait for end of HTTP tarpit */
|
168
|
|
-+#define AN_REQ_HTTP_BODY 0x00000100 /* inspect HTTP request body */
|
169
|
|
-+#define AN_REQ_STICKING_RULES 0x00000200 /* table persistence matching */
|
170
|
|
- #define AN_REQ_PRST_RDP_COOKIE 0x00000400 /* persistence on rdp cookie */
|
171
|
|
- #define AN_REQ_HTTP_XFER_BODY 0x00000800 /* forward request body */
|
172
|
|
-
|
173
|
|
-Index: haproxy-1.4.25/include/types/protocols.h
|
174
|
|
-===================================================================
|
175
|
|
---- haproxy-1.4.25.orig/include/types/protocols.h
|
176
|
|
-+++ haproxy-1.4.25/include/types/protocols.h
|
177
|
|
-@@ -72,6 +72,7 @@
|
178
|
|
- #define LI_O_FOREIGN 0x0002 /* permit listening on foreing addresses */
|
179
|
|
- #define LI_O_NOQUICKACK 0x0004 /* disable quick ack of immediate data (linux) */
|
180
|
|
- #define LI_O_DEF_ACCEPT 0x0008 /* wait up to 1 second for data before accepting */
|
181
|
|
-+#define LI_O_ACC_PROXY 0x0010 /* find the proxied address in the first request line */
|
182
|
|
-
|
183
|
|
- /* The listener will be directly referenced by the fdtab[] which holds its
|
184
|
|
- * socket. The listener provides the protocol-specific accept() function to
|
185
|
|
-Index: haproxy-1.4.25/src/cfgparse.c
|
186
|
|
-===================================================================
|
187
|
|
---- haproxy-1.4.25.orig/src/cfgparse.c
|
188
|
|
-+++ haproxy-1.4.25/src/cfgparse.c
|
189
|
|
-@@ -1467,6 +1467,16 @@ int cfg_parse_listen(const char *file, i
|
190
|
|
- #endif
|
191
|
|
- }
|
192
|
|
-
|
193
|
|
-+ if (!strcmp(args[cur_arg], "accept-proxy")) { /* expect a 'PROXY' line first */
|
194
|
|
-+ struct listener *l;
|
195
|
|
-+
|
196
|
|
-+ for (l = curproxy->listen; l != last_listen; l = l->next)
|
197
|
|
-+ l->options |= LI_O_ACC_PROXY;
|
198
|
|
-+
|
199
|
|
-+ cur_arg ++;
|
200
|
|
-+ continue;
|
201
|
|
-+ }
|
202
|
|
-+
|
203
|
|
- if (!strcmp(args[cur_arg], "name")) {
|
204
|
|
- struct listener *l;
|
205
|
|
-
|
206
|
|
-@@ -1519,7 +1529,7 @@ int cfg_parse_listen(const char *file, i
|
207
|
|
- continue;
|
208
|
|
- }
|
209
|
|
-
|
210
|
|
-- Alert("parsing [%s:%d] : '%s' only supports the 'transparent', 'defer-accept', 'name', 'id', 'mss' and 'interface' options.\n",
|
211
|
|
-+ Alert("parsing [%s:%d] : '%s' only supports the 'transparent', 'accept-proxy', 'defer-accept', 'name', 'id', 'mss' and 'interface' options.\n",
|
212
|
|
- file, linenum, args[0]);
|
213
|
|
- err_code |= ERR_ALERT | ERR_FATAL;
|
214
|
|
- goto out;
|
215
|
|
-@@ -5743,6 +5753,9 @@ out_uri_auth_compat:
|
216
|
|
- listener->handler = process_session;
|
217
|
|
- listener->analysers |= curproxy->fe_req_ana;
|
218
|
|
-
|
219
|
|
-+ if (listener->options & LI_O_ACC_PROXY)
|
220
|
|
-+ listener->analysers |= AN_REQ_DECODE_PROXY;
|
221
|
|
-+
|
222
|
|
- /* smart accept mode is automatic in HTTP mode */
|
223
|
|
- if ((curproxy->options2 & PR_O2_SMARTACC) ||
|
224
|
|
- (curproxy->mode == PR_MODE_HTTP &&
|
225
|
|
-Index: haproxy-1.4.25/src/client.c
|
226
|
|
-===================================================================
|
227
|
|
---- haproxy-1.4.25.orig/src/client.c
|
228
|
|
-+++ haproxy-1.4.25/src/client.c
|
229
|
|
-@@ -22,6 +22,7 @@
|
230
|
|
-
|
231
|
|
- #include <common/compat.h>
|
232
|
|
- #include <common/config.h>
|
233
|
|
-+#include <common/debug.h>
|
234
|
|
- #include <common/time.h>
|
235
|
|
-
|
236
|
|
- #include <types/global.h>
|
237
|
|
-@@ -43,6 +44,191 @@
|
238
|
|
- #include <proto/task.h>
|
239
|
|
-
|
240
|
|
-
|
241
|
|
-+/* This analyser tries to fetch a line from the request buffer which looks like :
|
242
|
|
-+ *
|
243
|
|
-+ * "PROXY" <SP> PROTO <SP> SRC3 <SP> DST3 <SP> SRC4 <SP> <DST4> "\r\n"
|
244
|
|
-+ *
|
245
|
|
-+ * There must be exactly one space between each field. Fields are :
|
246
|
|
-+ * - PROTO : layer 4 protocol, which must be "TCP4" or "TCP6".
|
247
|
|
-+ * - SRC3 : layer 3 (eg: IP) source address in standard text form
|
248
|
|
-+ * - DST3 : layer 3 (eg: IP) destination address in standard text form
|
249
|
|
-+ * - SRC4 : layer 4 (eg: TCP port) source address in standard text form
|
250
|
|
-+ * - DST4 : layer 4 (eg: TCP port) destination address in standard text form
|
251
|
|
-+ *
|
252
|
|
-+ * This line MUST be at the beginning of the buffer and MUST NOT wrap.
|
253
|
|
-+ *
|
254
|
|
-+ * Once the data is fetched, the values are set in the session's field and data
|
255
|
|
-+ * are removed from the buffer. The function returns zero if it needs to wait
|
256
|
|
-+ * for more data (max: timeout_client), or 1 if it has finished and removed itself.
|
257
|
|
-+ */
|
258
|
|
-+int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit)
|
259
|
|
-+{
|
260
|
|
-+ char *line = req->data;
|
261
|
|
-+ char *end = req->data + req->l;
|
262
|
|
-+ int len;
|
263
|
|
-+
|
264
|
|
-+ DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
|
265
|
|
-+ now_ms, __FUNCTION__,
|
266
|
|
-+ s,
|
267
|
|
-+ req,
|
268
|
|
-+ req->rex, req->wex,
|
269
|
|
-+ req->flags,
|
270
|
|
-+ req->l,
|
271
|
|
-+ req->analysers);
|
272
|
|
-+
|
273
|
|
-+ if (req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT))
|
274
|
|
-+ goto fail;
|
275
|
|
-+
|
276
|
|
-+ len = MIN(req->l, 6);
|
277
|
|
-+ if (!len)
|
278
|
|
-+ goto missing;
|
279
|
|
-+
|
280
|
|
-+ /* Decode a possible proxy request, fail early if it does not match */
|
281
|
|
-+ if (strncmp(line, "PROXY ", len) != 0)
|
282
|
|
-+ goto fail;
|
283
|
|
-+
|
284
|
|
-+ line += 6;
|
285
|
|
-+ if (req->l < 18) /* shortest possible line */
|
286
|
|
-+ goto missing;
|
287
|
|
-+
|
288
|
|
-+ if (!memcmp(line, "TCP4 ", 5) != 0) {
|
289
|
|
-+ u32 src3, dst3, sport, dport;
|
290
|
|
-+
|
291
|
|
-+ line += 5;
|
292
|
|
-+
|
293
|
|
-+ src3 = inetaddr_host_lim_ret(line, end, &line);
|
294
|
|
-+ if (line == end)
|
295
|
|
-+ goto missing;
|
296
|
|
-+ if (*line++ != ' ')
|
297
|
|
-+ goto fail;
|
298
|
|
-+
|
299
|
|
-+ dst3 = inetaddr_host_lim_ret(line, end, &line);
|
300
|
|
-+ if (line == end)
|
301
|
|
-+ goto missing;
|
302
|
|
-+ if (*line++ != ' ')
|
303
|
|
-+ goto fail;
|
304
|
|
-+
|
305
|
|
-+ sport = read_uint((const char **)&line, end);
|
306
|
|
-+ if (line == end)
|
307
|
|
-+ goto missing;
|
308
|
|
-+ if (*line++ != ' ')
|
309
|
|
-+ goto fail;
|
310
|
|
-+
|
311
|
|
-+ dport = read_uint((const char **)&line, end);
|
312
|
|
-+ if (line > end - 2)
|
313
|
|
-+ goto missing;
|
314
|
|
-+ if (*line++ != '\r')
|
315
|
|
-+ goto fail;
|
316
|
|
-+ if (*line++ != '\n')
|
317
|
|
-+ goto fail;
|
318
|
|
-+
|
319
|
|
-+ /* update the session's addresses and mark them set */
|
320
|
|
-+ ((struct sockaddr_in *)&s->cli_addr)->sin_family = AF_INET;
|
321
|
|
-+ ((struct sockaddr_in *)&s->cli_addr)->sin_addr.s_addr = htonl(src3);
|
322
|
|
-+ ((struct sockaddr_in *)&s->cli_addr)->sin_port = htons(sport);
|
323
|
|
-+
|
324
|
|
-+ ((struct sockaddr_in *)&s->frt_addr)->sin_family = AF_INET;
|
325
|
|
-+ ((struct sockaddr_in *)&s->frt_addr)->sin_addr.s_addr = htonl(dst3);
|
326
|
|
-+ ((struct sockaddr_in *)&s->frt_addr)->sin_port = htons(dport);
|
327
|
|
-+ s->flags |= SN_FRT_ADDR_SET;
|
328
|
|
-+
|
329
|
|
-+ }
|
330
|
|
-+ else if (!memcmp(line, "TCP6 ", 5) != 0) {
|
331
|
|
-+ u32 sport, dport;
|
332
|
|
-+ char *src_s;
|
333
|
|
-+ char *dst_s, *sport_s, *dport_s;
|
334
|
|
-+ struct in6_addr src3, dst3;
|
335
|
|
-+
|
336
|
|
-+ line+=5;
|
337
|
|
-+
|
338
|
|
-+ src_s = line;
|
339
|
|
-+ dst_s = sport_s = dport_s = NULL;
|
340
|
|
-+ while (1) {
|
341
|
|
-+ if (line > end - 2) {
|
342
|
|
-+ goto missing;
|
343
|
|
-+ }
|
344
|
|
-+ else if (*line == '\r') {
|
345
|
|
-+ *line = 0;
|
346
|
|
-+ line++;
|
347
|
|
-+ if (*line++ != '\n')
|
348
|
|
-+ goto fail;
|
349
|
|
-+ break;
|
350
|
|
-+ }
|
351
|
|
-+
|
352
|
|
-+ if (*line == ' ') {
|
353
|
|
-+ *line = 0;
|
354
|
|
-+ if (!dst_s)
|
355
|
|
-+ dst_s = line+1;
|
356
|
|
-+ else if (!sport_s)
|
357
|
|
-+ sport_s = line+1;
|
358
|
|
-+ else if (!dport_s)
|
359
|
|
-+ dport_s = line+1;
|
360
|
|
-+ }
|
361
|
|
-+ line++;
|
362
|
|
-+ }
|
363
|
|
-+
|
364
|
|
-+ if (!dst_s || !sport_s || !dport_s)
|
365
|
|
-+ goto fail;
|
366
|
|
-+
|
367
|
|
-+ sport = read_uint((const char **)&sport_s,dport_s-1);
|
368
|
|
-+ if ( *sport_s != 0 )
|
369
|
|
-+ goto fail;
|
370
|
|
-+
|
371
|
|
-+ dport = read_uint((const char **)&dport_s,line-2);
|
372
|
|
-+ if ( *dport_s != 0 )
|
373
|
|
-+ goto fail;
|
374
|
|
-+
|
375
|
|
-+ if (inet_pton(AF_INET6, src_s, (void *)&src3) != 1)
|
376
|
|
-+ goto fail;
|
377
|
|
-+
|
378
|
|
-+ if (inet_pton(AF_INET6, dst_s, (void *)&dst3) != 1)
|
379
|
|
-+ goto fail;
|
380
|
|
-+
|
381
|
|
-+ /* update the session's addresses and mark them set */
|
382
|
|
-+ ((struct sockaddr_in6 *)&s->cli_addr)->sin6_family = AF_INET6;
|
383
|
|
-+ memcpy(&((struct sockaddr_in6 *)&s->cli_addr)->sin6_addr, &src3, sizeof(struct in6_addr));
|
384
|
|
-+ ((struct sockaddr_in6 *)&s->cli_addr)->sin6_port = htons(sport);
|
385
|
|
-+
|
386
|
|
-+ ((struct sockaddr_in6 *)&s->frt_addr)->sin6_family = AF_INET6;
|
387
|
|
-+ memcpy(&((struct sockaddr_in6 *)&s->frt_addr)->sin6_addr, &dst3, sizeof(struct in6_addr));
|
388
|
|
-+ ((struct sockaddr_in6 *)&s->frt_addr)->sin6_port = htons(dport);
|
389
|
|
-+ s->flags |= SN_FRT_ADDR_SET;
|
390
|
|
-+ }
|
391
|
|
-+ else {
|
392
|
|
-+ goto fail;
|
393
|
|
-+ }
|
394
|
|
-+
|
395
|
|
-+ /* remove the PROXY line from the request */
|
396
|
|
-+ len = line - req->data;
|
397
|
|
-+ buffer_replace2(req, req->data, line, NULL, 0);
|
398
|
|
-+ req->total -= len; /* don't count the header line */
|
399
|
|
-+
|
400
|
|
-+ req->analysers &= ~an_bit;
|
401
|
|
-+ return 1;
|
402
|
|
-+
|
403
|
|
-+ missing:
|
404
|
|
-+ if (!(req->flags & (BF_SHUTR|BF_FULL))) {
|
405
|
|
-+ buffer_dont_connect(s->req);
|
406
|
|
-+ return 0;
|
407
|
|
-+ }
|
408
|
|
-+ /* missing data and buffer is either full or shutdown => fail */
|
409
|
|
-+
|
410
|
|
-+ fail:
|
411
|
|
-+ buffer_abort(req);
|
412
|
|
-+ buffer_abort(s->rep);
|
413
|
|
-+ req->analysers = 0;
|
414
|
|
-+
|
415
|
|
-+ s->fe->counters.failed_req++;
|
416
|
|
-+ if (s->listener->counters)
|
417
|
|
-+ s->listener->counters->failed_req++;
|
418
|
|
-+
|
419
|
|
-+ if (!(s->flags & SN_ERR_MASK))
|
420
|
|
-+ s->flags |= SN_ERR_PRXCOND;
|
421
|
|
-+ if (!(s->flags & SN_FINST_MASK))
|
422
|
|
-+ s->flags |= SN_FINST_R;
|
423
|
|
-+ return 0;
|
424
|
|
-+}
|
425
|
|
-+
|
426
|
|
- /* Retrieves the original destination address used by the client, and sets the
|
427
|
|
- * SN_FRT_ADDR_SET flag.
|
428
|
|
- */
|
429
|
|
-Index: haproxy-1.4.25/src/proto_http.c
|
430
|
|
-===================================================================
|
431
|
|
---- haproxy-1.4.25.orig/src/proto_http.c
|
432
|
|
-+++ haproxy-1.4.25/src/proto_http.c
|
433
|
|
-@@ -4209,7 +4209,8 @@ void http_end_txn_clean_session(struct s
|
434
|
|
- if (s->rep->lr >= s->rep->data + s->rep->size)
|
435
|
|
- s->rep->lr -= s->req->size;
|
436
|
|
-
|
437
|
|
-- s->req->analysers |= s->fe->fe_req_ana;
|
438
|
|
-+ s->req->analysers = s->fe->fe_req_ana;
|
439
|
|
-+ s->req->analysers &= ~AN_REQ_DECODE_PROXY;
|
440
|
|
- s->rep->analysers = 0;
|
441
|
|
-
|
442
|
|
- http_silent_debug(__LINE__, s);
|
443
|
|
-@@ -7807,7 +7808,6 @@ void http_reset_txn(struct session *s)
|
444
|
|
- http_init_txn(s);
|
445
|
|
-
|
446
|
|
- s->be = s->fe;
|
447
|
|
-- s->req->analysers = s->listener->analysers;
|
448
|
|
- s->logs.logwait = s->fe->to_log;
|
449
|
|
- s->srv = s->prev_srv = s->srv_conn = NULL;
|
450
|
|
- /* re-init store persistence */
|
451
|
|
-Index: haproxy-1.4.25/src/session.c
|
452
|
|
-===================================================================
|
453
|
|
---- haproxy-1.4.25.orig/src/session.c
|
454
|
|
-+++ haproxy-1.4.25/src/session.c
|
455
|
|
-@@ -34,6 +34,7 @@
|
456
|
|
- #include <proto/proxy.h>
|
457
|
|
- #include <proto/queue.h>
|
458
|
|
- #include <proto/server.h>
|
459
|
|
-+#include <proto/client.h>
|
460
|
|
- #include <proto/stick_table.h>
|
461
|
|
- #include <proto/stream_interface.h>
|
462
|
|
- #include <proto/stream_sock.h>
|
463
|
|
-@@ -1083,6 +1084,12 @@ resync_stream_interface:
|
464
|
|
- while (ana_list && max_loops--) {
|
465
|
|
- /* Warning! ensure that analysers are always placed in ascending order! */
|
466
|
|
-
|
467
|
|
-+ if (ana_list & AN_REQ_DECODE_PROXY) {
|
468
|
|
-+ if (!frontend_decode_proxy_request(s, s->req, AN_REQ_DECODE_PROXY))
|
469
|
|
-+ break;
|
470
|
|
-+ UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_DECODE_PROXY);
|
471
|
|
-+ }
|
472
|
|
-+
|
473
|
|
- if (ana_list & AN_REQ_INSPECT) {
|
474
|
|
- if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT))
|
475
|
|
- break;
|
476
|
|
-Index: haproxy-1.4.25/src/standard.c
|
477
|
|
-===================================================================
|
478
|
|
---- haproxy-1.4.25.orig/src/standard.c
|
479
|
|
-+++ haproxy-1.4.25/src/standard.c
|
480
|
|
-@@ -569,6 +569,11 @@ unsigned int strl2uic(const char *s, int
|
481
|
|
- return __strl2uic(s, len);
|
482
|
|
- }
|
483
|
|
-
|
484
|
|
-+unsigned int read_uint(const char **s, const char *end)
|
485
|
|
-+{
|
486
|
|
-+ return __read_uint(s, end);
|
487
|
|
-+}
|
488
|
|
-+
|
489
|
|
- /* This one is 7 times faster than strtol() on athlon with checks.
|
490
|
|
- * It returns the value of the number composed of all valid digits read,
|
491
|
|
- * and can process negative numbers too.
|
492
|
|
-@@ -993,12 +998,12 @@ unsigned int inetaddr_host_lim(const cha
|
493
|
|
- * Idem except the pointer to first unparsed byte is returned into <ret> which
|
494
|
|
- * must not be NULL.
|
495
|
|
- */
|
496
|
|
--unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret)
|
497
|
|
-+unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret)
|
498
|
|
- {
|
499
|
|
- const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0';
|
500
|
|
- register unsigned int dig100, dig10, dig1;
|
501
|
|
- int s;
|
502
|
|
-- const char *p, *d;
|
503
|
|
-+ char *p, *d;
|
504
|
|
-
|
505
|
|
- dig1 = dig10 = dig100 = ascii_zero;
|
506
|
|
- s = 24;
|