Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV, from PROXYv2

2019-08-27 Thread Geoff Simmons
This is with the fix for the misplaced #endif spotted by Emmanuel, thx
again.


Geoff
-- 
** * * UPLEX - Nils Goroll Systemoptimierung

Scheffelstraße 32
22301 Hamburg

Tel +49 40 2880 5731
Mob +49 176 636 90917
Fax +49 40 42949753

http://uplex.de



signature.asc
Description: OpenPGP digital signature


[PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV, from PROXYv2

2019-08-27 Thread Geoff Simmons
Save the authority TLV in a PROXYv2 header from the client connection,
if present, and make it available as fc_pp_authority.

The fetch can be used, for example, to set the SNI for a backend TLS
connection.
---
 doc/configuration.txt  |  4 
 include/proto/connection.h |  7 +++
 include/types/connection.h |  4 
 src/connection.c   | 37 +
 4 files changed, 52 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 4e18f0f6e..4c820d266 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -14460,6 +14460,10 @@ fc_http_major : integer
   for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire
   encoding and not on the version present in the request header.
 
+fc_pp_authority : string
+  Returns the authority TLV sent by the client in the PROXY protocol header,
+  if any.
+
 fc_rcvd_proxy : boolean
   Returns true if the client initiated the connection with a PROXY protocol
   header.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index bbb9759ac..059d5d85a 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -35,6 +35,7 @@
 extern struct pool_head *pool_head_connection;
 extern struct pool_head *pool_head_connstream;
 extern struct pool_head *pool_head_sockaddr;
+extern struct pool_head *pool_head_authority;
 extern struct xprt_ops *registered_xprt[XPRT_ENTRIES];
 extern struct mux_proto_list mux_proto_list;
 
@@ -471,6 +472,7 @@ static inline void conn_init(struct connection *conn)
conn->idle_time = 0;
conn->src = NULL;
conn->dst = NULL;
+   conn->proxy_authority = NULL;
 }
 
 /* sets  as the connection's owner */
@@ -617,6 +619,11 @@ static inline void conn_free(struct connection *conn)
sockaddr_free(>src);
sockaddr_free(>dst);
 
+   if (conn->proxy_authority != NULL) {
+   pool_free(pool_head_authority, conn->proxy_authority);
+   conn->proxy_authority = NULL;
+   }
+
/* By convention we always place a NULL where the ctx points to if the
 * mux is null. It may have been used to store the connection as a
 * stream_interface's end point for example.
diff --git a/include/types/connection.h b/include/types/connection.h
index f8e4c07f9..f6a7d1b7e 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -461,7 +461,9 @@ struct connection {
void (*destroy_cb)(struct connection *conn);  /* callback to notify of 
imminent death of the connection */
struct sockaddr_storage *src; /* source address (pool), when known, 
otherwise NULL */
struct sockaddr_storage *dst; /* destination address (pool), when 
known, otherwise NULL */
+   char *proxy_authority;/* Value of authority TLV received via 
PROXYv2 */
unsigned int idle_time; /* Time the connection was 
added to the idle list, or 0 if not in the idle list */
+   uint8_t proxy_authority_len;  /* Length of authority TLV received via 
PROXYv2 */
 };
 
 /* PROTO token registration */
@@ -578,6 +580,8 @@ struct tlv_ssl {
 #define PP2_CLIENT_CERT_CONN 0x02
 #define PP2_CLIENT_CERT_SESS 0x04
 
+/* Max length of the authority TLV */
+#define PP2_AUTHORITY_MAX 255
 
 /*
  * Linux seems to be able to send 253 fds per sendmsg(), not sure
diff --git a/src/connection.c b/src/connection.c
index 602fc79ec..7bdd6f0dd 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -32,6 +32,7 @@
 DECLARE_POOL(pool_head_connection, "connection",  sizeof(struct connection));
 DECLARE_POOL(pool_head_connstream, "conn_stream", sizeof(struct conn_stream));
 DECLARE_POOL(pool_head_sockaddr,   "sockaddr",sizeof(struct 
sockaddr_storage));
+DECLARE_POOL(pool_head_authority,  "authority",   PP2_AUTHORITY_MAX);
 
 struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, };
 
@@ -631,6 +632,16 @@ int conn_recv_proxy(struct connection *conn, int flag)
break;
}
 #endif
+   case PP2_TYPE_AUTHORITY: {
+   if (tlv_len > PP2_AUTHORITY_MAX)
+   goto bad_header;
+   conn->proxy_authority = 
pool_alloc(pool_head_authority);
+   if (conn->proxy_authority == NULL)
+   goto fail;
+   memcpy(conn->proxy_authority, (const 
char *)tlv_packet->value, tlv_len);
+   conn->proxy_authority_len = tlv_len;
+   break;
+   }
default:
break;
}
@@ -1415,6 +1426,31 @@ int smp_fetch_fc_rcvd_proxy(const struct arg *args, 
struct sample *smp, const ch
 

Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2

2019-08-27 Thread Geoff Simmons
On 8/27/19 18:15, Emmanuel Hocdet wrote:
> 
>> @@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag)
>>  conn->proxy_netns = ns;
>>  break;
>>  }
>> +
>> +case PP2_TYPE_AUTHORITY: {
> 
> Is inside #ifdef USE_NS

Oh, now I see it. Will fix.


Thx,
Geoff
-- 
** * * UPLEX - Nils Goroll Systemoptimierung

Scheffelstraße 32
22301 Hamburg

Tel +49 40 2880 5731
Mob +49 176 636 90917
Fax +49 40 42949753

http://uplex.de



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2

2019-08-27 Thread Emmanuel Hocdet
Hi Geoff,


For:
> 
> @@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag)
>   conn->proxy_netns = ns;
>   break;
>   }
> +
> + case PP2_TYPE_AUTHORITY: {

Is inside #ifdef USE_NS

It work for me, with the #ifdef fix.

Thanks
Manu



Re: [RFC] setting the backend SNI from the client's authority TLV, when the target address was forwarded

2019-08-27 Thread Emmanuel Hocdet


> Le 22 août 2019 à 14:40, Willy Tarreau  a écrit :
> 
> On Thu, Aug 22, 2019 at 11:36:00AM +0200, Geoff Simmons wrote:
> 
>> I suspect that there are other ways that the authority TLV can be useful
>> for haproxy besides the specific Varnish case. Someone connecting via
>> TLS, for example, might want to send the TLV to "override" the SNI for
>> certain backends.
> 
> It's definitely useful for other cases, which is why I'm interested in
> seeing it addressed properly. Right now we do emit a few fields in the
> PPv2 but we ignore them on receipt, which is a bit sad. For example, if
> you use multi-process to chain two haproxy instances, one with TLS
> offloading, passing to the next level using PPv2, you currently lose the
> SNI information. With your change it would finally work.
> 

Indeed, the receipt part of PPv2 has been postponed until needed.

With authority received from PPv2 (Geoff patch), i see use cases  (one is to 
test 
configuration like chaining tow haproxy :-) )
To generalize the usage of authority,  i will see a get_authority func in 
xprt_ops.
With a ssl connection: return the sni (aka ssl authority).
With a tcp connection: return the ppv2 authority.
So a « send-proxy-v2   proxy-v2-options authority » server line will work in 
both cases.

To override the authority, is like « sni » for server line, we could used « 
authority ».
«  send-proxy-v2   authority  hdr(Host) proxy-v2-options authority » 

For server line with ssl, i thought that « authority » could replace « sni » 
but we can have both:
«  ssl sni hdr(Host),lower  send-proxy-v2   authority  hdr(Host) 
proxy-v2-options authority »

Note:
in my test «  sni hdr(Host),lower » work but « sni var(req.host) » doesn’t  
(with http-request content set-var(req.host) hdr(host),lower )

What do you think?

Manu





[PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2

2019-08-27 Thread Geoff Simmons
Save the authority TLV sent in a PROXYv2 header from the client
connection, if present, and make it available as fc_pp_authority.

The fetch can be used, for example, to set the SNI for a backend TLS
connection.
---
 doc/configuration.txt  |  4 
 include/proto/connection.h |  7 +++
 include/types/connection.h |  4 
 src/connection.c   | 38 ++
 4 files changed, 53 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 4e18f0f6e..4c820d266 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -14460,6 +14460,10 @@ fc_http_major : integer
   for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire
   encoding and not on the version present in the request header.
 
+fc_pp_authority : string
+  Returns the authority TLV sent by the client in the PROXY protocol header,
+  if any.
+
 fc_rcvd_proxy : boolean
   Returns true if the client initiated the connection with a PROXY protocol
   header.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index bbb9759ac..059d5d85a 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -35,6 +35,7 @@
 extern struct pool_head *pool_head_connection;
 extern struct pool_head *pool_head_connstream;
 extern struct pool_head *pool_head_sockaddr;
+extern struct pool_head *pool_head_authority;
 extern struct xprt_ops *registered_xprt[XPRT_ENTRIES];
 extern struct mux_proto_list mux_proto_list;
 
@@ -471,6 +472,7 @@ static inline void conn_init(struct connection *conn)
conn->idle_time = 0;
conn->src = NULL;
conn->dst = NULL;
+   conn->proxy_authority = NULL;
 }
 
 /* sets  as the connection's owner */
@@ -617,6 +619,11 @@ static inline void conn_free(struct connection *conn)
sockaddr_free(>src);
sockaddr_free(>dst);
 
+   if (conn->proxy_authority != NULL) {
+   pool_free(pool_head_authority, conn->proxy_authority);
+   conn->proxy_authority = NULL;
+   }
+
/* By convention we always place a NULL where the ctx points to if the
 * mux is null. It may have been used to store the connection as a
 * stream_interface's end point for example.
diff --git a/include/types/connection.h b/include/types/connection.h
index f8e4c07f9..f6a7d1b7e 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -461,7 +461,9 @@ struct connection {
void (*destroy_cb)(struct connection *conn);  /* callback to notify of 
imminent death of the connection */
struct sockaddr_storage *src; /* source address (pool), when known, 
otherwise NULL */
struct sockaddr_storage *dst; /* destination address (pool), when 
known, otherwise NULL */
+   char *proxy_authority;/* Value of authority TLV received via 
PROXYv2 */
unsigned int idle_time; /* Time the connection was 
added to the idle list, or 0 if not in the idle list */
+   uint8_t proxy_authority_len;  /* Length of authority TLV received via 
PROXYv2 */
 };
 
 /* PROTO token registration */
@@ -578,6 +580,8 @@ struct tlv_ssl {
 #define PP2_CLIENT_CERT_CONN 0x02
 #define PP2_CLIENT_CERT_SESS 0x04
 
+/* Max length of the authority TLV */
+#define PP2_AUTHORITY_MAX 255
 
 /*
  * Linux seems to be able to send 253 fds per sendmsg(), not sure
diff --git a/src/connection.c b/src/connection.c
index 602fc79ec..a4f9fdbac 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -32,6 +32,7 @@
 DECLARE_POOL(pool_head_connection, "connection",  sizeof(struct connection));
 DECLARE_POOL(pool_head_connstream, "conn_stream", sizeof(struct conn_stream));
 DECLARE_POOL(pool_head_sockaddr,   "sockaddr",sizeof(struct 
sockaddr_storage));
+DECLARE_POOL(pool_head_authority,  "authority",   PP2_AUTHORITY_MAX);
 
 struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, };
 
@@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag)
conn->proxy_netns = ns;
break;
}
+
+   case PP2_TYPE_AUTHORITY: {
+   if (tlv_len > PP2_AUTHORITY_MAX)
+   goto bad_header;
+   conn->proxy_authority = 
pool_alloc(pool_head_authority);
+   if (conn->proxy_authority == NULL)
+   goto fail;
+   memcpy(conn->proxy_authority, (const 
char *)tlv_packet->value, tlv_len);
+   conn->proxy_authority_len = tlv_len;
+   break;
+   }
 #endif
default:
break;
@@ -1415,6 +1427,31 @@ int smp_fetch_fc_rcvd_proxy(const struct