Re: Generic backend in HAProxy config with server options as placeholders

2018-11-14 Thread Vijay Bais
On Thu, Nov 15, 2018 at 4:07 AM Igor Cicimov 
wrote:

>
>
> On Thu, Nov 15, 2018 at 1:36 AM Aleksandar Lazic 
> wrote:
>
>> Hi Vijay.
>>
>> Am 14.11.2018 um 10:14 schrieb Vijay Bais:
>> > Hello Aleksandar,
>> >
>> > We already considered using haproxy maps but we still have to define N
>> backends
>> > for corresponding N keys in the map file.
>> > I'm looking more at an implementation with single backend definition
>> with the
>> > server options as placeholders.
>> >
>> > Ex. Using maps would look something like this
>> >
>> > frontend nat
>> > bind *:1
>> > use_backend %[req.hdr(X-MyHeader), map(/etc/haproxy/my.map)]
>> >
>> > backend example1.com
>> > server myserver1 example1.com:80 source 10.0.0.1
>> >
>> > backend example2.com
>> > server myserver2 example2.com:80 source 10.0.0.2
>> >
>> > backend example3.com
>> > server myserver3 example3.com:80 source 10.0.0.3
>> >
>> >
>> >
>> > Whereas, we are looking for something like below
>> >
>> >
>> > frontend nat
>> > bind *:1
>> > default_backend generic
>> >
>> > backend generic
>> > server myserver %[req.hdr(X-MyHeader)] source %[dst]
>>
>> Ah now concrete examples ;-)
>>
>> Maybe you can use the server template?!
>>
>> https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-server-template
>>
>> So you would like to have something like this, is this possible, I don't
>> think so?
>>
>> backend generic
>>   server-template myserver 1-3 %[req.hdr(X-MyHeader)]:80 check source
>> 0.0.0.0
>> usesrc %[dst]
>>
> @Aleksandar Lazic  tried using server-template, but
it won't work


>
>> Which version of HAProxy do you use?
>>
> We are using v1.8.13


>> haproxy -vv
>>
>  HA-Proxy version 1.8.13 2018/07/30
Copyright 2000-2018 Willy Tarreau 

Build options :
  TARGET  = linux2628
  CPU = generic
  CC  = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
-fwrapv -fno-strict-overflow -Wno-unused-label
  OPTIONS = USE_LINUX_TPROXY=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1
USE_LUA=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with network namespace support.
Built with zlib version : 1.2.3
Running on zlib version : 1.2.8
Compression algorithms supported : identity("identity"),
deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with PCRE version : 7.8 2008-09-05
Running on PCRE version : 8.21 2011-12-12
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with multi-threading support.
Encrypted password support via crypt(3): yes
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT
IP_FREEBIND
Built with Lua version : Lua 5.3.4
Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2

Available polling systems :
  epoll : pref=300,  test result OK
   poll : pref=200,  test result OK
 select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
[TRACE] trace
[COMP] compression
[SPOE] spoe


>> > Thanks,
>> > Vijay
>>
>> Regards
>> Aleks
>>
>> > On Wed, Nov 14, 2018 at 1:39 PM Aleksandar Lazic > > > wrote:
>> >
>> > Hi.
>> >
>> > Am 14.11.2018 um 08:46 schrieb Vijay Bais:
>> > > Hello,
>> > >
>> > > We have a requirement wherein a single generic backend with
>> server options
>> > > configured as placeholders, which will resolve on the fly or at
>> runtime.
>> > >
>> > > Currently, we have to define multiple backends (has to be
>> hardcoded) and
>> > select
>> > > them using the /use_backend/ keyword.
>> > >
>> > > Kindly help us with this generic backend implementation in
>> HAProxy and let us
>> > > know if its possible OR any alternative way that this can be
>> achieved.
>> >
>> > Maybe you can use maps for your requirement.
>> >
>> > https://www.haproxy.com/blog/introduction-to-haproxy-maps/
>> >
>> > As an example can you take a look at the openshift router template
>> ;-)
>> >
>> >
>> https://github.com/openshift/origin/blob/master/images/router/haproxy/conf/haproxy-config.template#L201-L202
>> >
>> > > Thank you in advance,
>> > > Vijay B
>> >
>> > Regards
>> > Aleks
>>
>
> You will need something dynamic like described here
> https://www.haproxy.com/blog/haproxy-and-consul-with-dns-for-service-discovery/
>
Thanks Igor! Let me explore this and get back :)


Re: Generic backend in HAProxy config with server options as placeholders

2018-11-14 Thread Igor Cicimov
On Thu, Nov 15, 2018 at 1:36 AM Aleksandar Lazic  wrote:

> Hi Vijay.
>
> Am 14.11.2018 um 10:14 schrieb Vijay Bais:
> > Hello Aleksandar,
> >
> > We already considered using haproxy maps but we still have to define N
> backends
> > for corresponding N keys in the map file.
> > I'm looking more at an implementation with single backend definition
> with the
> > server options as placeholders.
> >
> > Ex. Using maps would look something like this
> >
> > frontend nat
> > bind *:1
> > use_backend %[req.hdr(X-MyHeader), map(/etc/haproxy/my.map)]
> >
> > backend example1.com
> > server myserver1 example1.com:80 source 10.0.0.1
> >
> > backend example2.com
> > server myserver2 example2.com:80 source 10.0.0.2
> >
> > backend example3.com
> > server myserver3 example3.com:80 source 10.0.0.3
> >
> >
> >
> > Whereas, we are looking for something like below
> >
> >
> > frontend nat
> > bind *:1
> > default_backend generic
> >
> > backend generic
> > server myserver %[req.hdr(X-MyHeader)] source %[dst]
>
> Ah now concrete examples ;-)
>
> Maybe you can use the server template?!
>
> https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-server-template
>
> So you would like to have something like this, is this possible, I don't
> think so?
>
> backend generic
>   server-template myserver 1-3 %[req.hdr(X-MyHeader)]:80 check source
> 0.0.0.0
> usesrc %[dst]
>
> Which version of HAProxy do you use?
>
> haproxy -vv
>
> > Thanks,
> > Vijay
>
> Regards
> Aleks
>
> > On Wed, Nov 14, 2018 at 1:39 PM Aleksandar Lazic  > > wrote:
> >
> > Hi.
> >
> > Am 14.11.2018 um 08:46 schrieb Vijay Bais:
> > > Hello,
> > >
> > > We have a requirement wherein a single generic backend with server
> options
> > > configured as placeholders, which will resolve on the fly or at
> runtime.
> > >
> > > Currently, we have to define multiple backends (has to be
> hardcoded) and
> > select
> > > them using the /use_backend/ keyword.
> > >
> > > Kindly help us with this generic backend implementation in HAProxy
> and let us
> > > know if its possible OR any alternative way that this can be
> achieved.
> >
> > Maybe you can use maps for your requirement.
> >
> > https://www.haproxy.com/blog/introduction-to-haproxy-maps/
> >
> > As an example can you take a look at the openshift router template
> ;-)
> >
> >
> https://github.com/openshift/origin/blob/master/images/router/haproxy/conf/haproxy-config.template#L201-L202
> >
> > > Thank you in advance,
> > > Vijay B
> >
> > Regards
> > Aleks
>

You will need something dynamic like described here
https://www.haproxy.com/blog/haproxy-and-consul-with-dns-for-service-discovery/


Re: [PATCH] BUG/CRITICAL: SIGBUS crash on aarch64

2018-11-14 Thread Olivier Houchard
Hi Paul,

On Wed, Nov 14, 2018 at 03:33:02PM +, Paul Martin wrote:
> Atomic operations on aarch64 (arm64) have to be aligned to 8 byte
> boundaries (same size as a pointer type), otherwise a SIGBUS is raised.
> 
> Because the variable ts here isn't guaranteed to be aligned due to the
> various data_size adjustments, make sure that data_size is always
> incremented by a minimum of sizeof(int *) rather than sizeof(int).
> 
> Program received signal SIGBUS, Bus error.
> 0xaab1176c in process_store_rules (s=s@entry=0xaae01060,
> rep=0xaae010d0, rep=0xaae010d0, an_bit=8388608)
> at src/stream.c:1609
> 1609HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
> (gdb) bt
> %0  0xaab1176c in process_store_rules (s=s@entry=0xaae01060,
> rep=0xaae010d0, rep=0xaae010d0, an_bit=8388608)
> at src/stream.c:1609
> %1  0xaab18898 in process_stream (t=,
> context=0xaae01060, state=) at src/stream.c:2054
> %2  0xaabb0220 in process_runnable_tasks () at src/task.c:421
> %3  0xaab51b40 in run_poll_loop () at src/haproxy.c:2609
> %4  run_thread_poll_loop (data=) at src/haproxy.c:2674
> %5  0xaaac715c in main (argc=, argv=0xf290)
> at src/haproxy.c:3286
> ---
>  include/proto/stick_table.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h
> index 40bb8ca6..6e39ad47 100644
> --- a/include/proto/stick_table.h
> +++ b/include/proto/stick_table.h
> @@ -64,7 +64,7 @@ static inline int stktable_type_size(int type)
>   switch(type) {
>   case STD_T_SINT:
>   case STD_T_UINT:
> - return sizeof(int);
> + return sizeof(int *);
>   case STD_T_ULL:
>   return sizeof(unsigned long long);
>   case STD_T_FRQP:

Oops, you're right indeed.
I'm not sure I'm a big fan of special-casing STD_T_UINT. For example,
STD_T_FRQP is probably 12bytes too, so it'd be a problem.
Can you test the (untested, but hopefully right) patch attached ?

Thanks a lot !

Olivier
>From 50027352049d64b874e1116758400580541ea49f Mon Sep 17 00:00:00 2001
From: Olivier Houchard 
Date: Wed, 14 Nov 2018 17:54:36 +0100
Subject: [PATCH] BUG/MEDIUM: Make sure stksess is properly aligned.

When we allocate struct stksess, we also allocate memory to store the
associated data before the struct itself.
As the data can be of different types, they can have different size. However,
we need the struct stksess to be properly aligned, as it can do 64bits
load/store (including atomic load/stores) on 64bits platforms, and some of
them doesn't support unaligned access.
So, when allocating the struct stksess, round the size up to the next
multiple of sizeof(void *), and make sure the struct stksess itself is
properly aligned.
Many thanks to Paul Martin for investigating and reporting that bug.
---
 src/stick_table.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/stick_table.c b/src/stick_table.c
index 7f141631..4ec7861e 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -45,6 +45,7 @@
 /* structure used to return a table key built from a sample */
 static THREAD_LOCAL struct stktable_key static_table_key;
 
+#define round_ptr_size(i) ((i + (sizeof(void *) - 1)) &~ (sizeof(void *) - 1))
 /*
  * Free an allocated sticky session , and decrease sticky sessions counter
  * in table .
@@ -52,7 +53,7 @@ static THREAD_LOCAL struct stktable_key static_table_key;
 void __stksess_free(struct stktable *t, struct stksess *ts)
 {
t->current--;
-   pool_free(t->pool, (void *)ts - t->data_size);
+   pool_free(t->pool, (void *)ts - round_ptr_size(t->data_size));
 }
 
 /*
@@ -230,7 +231,7 @@ struct stksess *__stksess_new(struct stktable *t, struct 
stktable_key *key)
ts = pool_alloc(t->pool);
if (ts) {
t->current++;
-   ts = (void *)ts + t->data_size;
+   ts = (void *)ts + round_ptr_size(t->data_size);
__stksess_init(t, ts);
if (key)
stksess_setkey(t, ts, key);
@@ -598,7 +599,7 @@ int stktable_init(struct stktable *t)
t->updates = EB_ROOT_UNIQUE;
HA_SPIN_INIT(&t->lock);
 
-   t->pool = create_pool("sticktables", sizeof(struct stksess) + 
t->data_size + t->key_size, MEM_F_SHARED);
+   t->pool = create_pool("sticktables", sizeof(struct stksess) + 
round_ptr_size(t->data_size) + t->key_size, MEM_F_SHARED);
 
t->exp_next = TICK_ETERNITY;
if ( t->expire ) {
-- 
2.17.1



[PATCH] BUG/CRITICAL: SIGBUS crash on aarch64

2018-11-14 Thread Paul Martin
Atomic operations on aarch64 (arm64) have to be aligned to 8 byte
boundaries (same size as a pointer type), otherwise a SIGBUS is raised.

Because the variable ts here isn't guaranteed to be aligned due to the
various data_size adjustments, make sure that data_size is always
incremented by a minimum of sizeof(int *) rather than sizeof(int).

Program received signal SIGBUS, Bus error.
0xaab1176c in process_store_rules (s=s@entry=0xaae01060,
rep=0xaae010d0, rep=0xaae010d0, an_bit=8388608)
at src/stream.c:1609
1609HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
(gdb) bt
%0  0xaab1176c in process_store_rules (s=s@entry=0xaae01060,
rep=0xaae010d0, rep=0xaae010d0, an_bit=8388608)
at src/stream.c:1609
%1  0xaab18898 in process_stream (t=,
context=0xaae01060, state=) at src/stream.c:2054
%2  0xaabb0220 in process_runnable_tasks () at src/task.c:421
%3  0xaab51b40 in run_poll_loop () at src/haproxy.c:2609
%4  run_thread_poll_loop (data=) at src/haproxy.c:2674
%5  0xaaac715c in main (argc=, argv=0xf290)
at src/haproxy.c:3286
---
 include/proto/stick_table.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h
index 40bb8ca6..6e39ad47 100644
--- a/include/proto/stick_table.h
+++ b/include/proto/stick_table.h
@@ -64,7 +64,7 @@ static inline int stktable_type_size(int type)
switch(type) {
case STD_T_SINT:
case STD_T_UINT:
-   return sizeof(int);
+   return sizeof(int *);
case STD_T_ULL:
return sizeof(unsigned long long);
case STD_T_FRQP:
-- 
2.19.1



haproxy segfaults when clearing the input buffer via LUA

2018-11-14 Thread Moemen MHEDHBI
Hi,

I was playing with LUA, to configure a traffic mirroring behavior.
Basically I wanted HAProxy to send the http response of a request to a
3rd party before sending the response to the client.

So this is the stripped down version of the script to reproduce the
segfault with haproxy from the master branch:

function mirror(txn)
    local in_len = txn.res:get_in_len()
    while in_len > 0 do
    response = txn.res:dup()
    -- sending response to 3rd party.
    txn.res:forward(in_len)
    core.yield()
    in_len = txn.res:get_in_len()
    end
end
core.register_action("mirror", { "http-res" }, mirror)

Then I use this script via "http-response lua.mirror"


I think problem here is that when I forward the response from the input
buffer to the output buffer and hand processing back to HAProyx, the
latter will try to send an invalid http request.

The request is invalid because HAProxy did not have the opportunity to
check the response and make sure there are valid headers because the
input buffer is empty after the core.yield().

So I was expecting an error and HAProxy telling me that this is an
invalid request but not a segfault.

There are two ways to avoid this by changing the script:

1/ Use mode tcp

2/ Use "get" and "send" instead of "forward", this way the LUA script
will send the response directly to the client, instead of HAProxy doing
that.

-- 
Moemen MHEDHBI



Re: Generic backend in HAProxy config with server options as placeholders

2018-11-14 Thread Aleksandar Lazic
Hi Vijay.

Am 14.11.2018 um 10:14 schrieb Vijay Bais:
> Hello Aleksandar,
> 
> We already considered using haproxy maps but we still have to define N 
> backends
> for corresponding N keys in the map file.
> I'm looking more at an implementation with single backend definition with the
> server options as placeholders.
> 
> Ex. Using maps would look something like this
> 
> frontend nat
>     bind *:1
>     use_backend %[req.hdr(X-MyHeader), map(/etc/haproxy/my.map)]
> 
> backend example1.com 
>     server myserver1 example1.com:80 source 10.0.0.1
> 
> backend example2.com
>     server myserver2 example2.com:80 source 10.0.0.2
> 
> backend example3.com
>     server myserver3 example3.com:80 source 10.0.0.3
> 
> 
> 
> Whereas, we are looking for something like below
> 
> 
> frontend nat
>     bind *:1
>     default_backend generic
> 
> backend generic
>     server myserver %[req.hdr(X-MyHeader)] source %[dst]

Ah now concrete examples ;-)

Maybe you can use the server template?!
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-server-template

So you would like to have something like this, is this possible, I don't think 
so?

backend generic
  server-template myserver 1-3 %[req.hdr(X-MyHeader)]:80 check source 0.0.0.0
usesrc %[dst]

Which version of HAProxy do you use?

haproxy -vv

> Thanks,
> Vijay

Regards
Aleks

> On Wed, Nov 14, 2018 at 1:39 PM Aleksandar Lazic  > wrote:
> 
> Hi.
> 
> Am 14.11.2018 um 08:46 schrieb Vijay Bais:
> > Hello,
> >
> > We have a requirement wherein a single generic backend with server 
> options
> > configured as placeholders, which will resolve on the fly or at runtime.
> >
> > Currently, we have to define multiple backends (has to be hardcoded) and
> select
> > them using the /use_backend/ keyword.
> >
> > Kindly help us with this generic backend implementation in HAProxy and 
> let us
> > know if its possible OR any alternative way that this can be achieved.
> 
> Maybe you can use maps for your requirement.
> 
> https://www.haproxy.com/blog/introduction-to-haproxy-maps/
> 
> As an example can you take a look at the openshift router template ;-)
> 
> 
> https://github.com/openshift/origin/blob/master/images/router/haproxy/conf/haproxy-config.template#L201-L202
> 
> > Thank you in advance,
> > Vijay B
> 
> Regards
> Aleks
> 




Re: Generic backend in HAProxy config with server options as placeholders

2018-11-14 Thread Vijay Bais
Hello Aleksandar,

We already considered using haproxy maps but we still have to define N
backends for corresponding N keys in the map file.
I'm looking more at an implementation with single backend definition with
the server options as placeholders.

Ex. Using maps would look something like this

frontend nat
bind *:1
use_backend %[req.hdr(X-MyHeader), map(/etc/haproxy/my.map)]

backend example1.com:80
server myserver1 example1.com:80 source 10.0.0.1

backend example2.com:80
server myserver2 example2.com:80 source 10.0.0.2

backend example3.com:80
server myserver3 example3.com:80 source 10.0.0.3



Whereas, we are looking for something like below


frontend nat
bind *:1
default_backend generic

backend generic
server myserver %[req.hdr(X-MyHeader)] source %[dst]


Thanks,
Vijay

On Wed, Nov 14, 2018 at 1:39 PM Aleksandar Lazic  wrote:

> Hi.
>
> Am 14.11.2018 um 08:46 schrieb Vijay Bais:
> > Hello,
> >
> > We have a requirement wherein a single generic backend with server
> options
> > configured as placeholders, which will resolve on the fly or at runtime.
> >
> > Currently, we have to define multiple backends (has to be hardcoded) and
> select
> > them using the /use_backend/ keyword.
> >
> > Kindly help us with this generic backend implementation in HAProxy and
> let us
> > know if its possible OR any alternative way that this can be achieved.
>
> Maybe you can use maps for your requirement.
>
> https://www.haproxy.com/blog/introduction-to-haproxy-maps/
>
> As an example can you take a look at the openshift router template ;-)
>
>
> https://github.com/openshift/origin/blob/master/images/router/haproxy/conf/haproxy-config.template#L201-L202
>
> > Thank you in advance,
> > Vijay B
>
> Regards
> Aleks
>


Re: Generic backend in HAProxy config with server options as placeholders

2018-11-14 Thread Aleksandar Lazic
Hi.

Am 14.11.2018 um 08:46 schrieb Vijay Bais:
> Hello,
> 
> We have a requirement wherein a single generic backend with server options
> configured as placeholders, which will resolve on the fly or at runtime.
> 
> Currently, we have to define multiple backends (has to be hardcoded) and 
> select
> them using the /use_backend/ keyword.
> 
> Kindly help us with this generic backend implementation in HAProxy and let us
> know if its possible OR any alternative way that this can be achieved.

Maybe you can use maps for your requirement.

https://www.haproxy.com/blog/introduction-to-haproxy-maps/

As an example can you take a look at the openshift router template ;-)

https://github.com/openshift/origin/blob/master/images/router/haproxy/conf/haproxy-config.template#L201-L202

> Thank you in advance,
> Vijay B

Regards
Aleks