diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2bfd314e3..430b0ca88 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -12733,6 +12733,16 @@ dst_conn : integer
different limits to different listening ports or addresses. See also the
"fe_conn" and "be_conn" fetches.
+dst_is_local : boolean
+ Returns true if the destination address of the incoming connection is local
+ to the system, or false if the address doesn't exist on the system, meaning
+ that it was intercepted in transparent mode. It can be useful to apply
+ certain rules by default to forwarded traffic and other rules to the traffic
+ targetting the real address of the machine. For example the stats page could
+ be delivered only on this address, or SSH access could be locally redirected.
+ Please note that the check involves a few system calls, so it's better to do
+ it only once per connection.
+
dst_port : integer
Returns an integer value corresponding to the destination TCP port of the
connection on the client side, which is the port the client connected to.
@@ -13076,6 +13086,15 @@ src_inc_gpc0([
]) : integer
acl kill src_inc_gpc0 gt 0
tcp-request connection reject if abuse kill
+src_is_local : boolean
+ Returns true if the source address of the incoming connection is local to the
+ system, or false if the address doesn't exist on the system, meaning that it
+ comes from a remote machine. Note that UNIX addresses are considered local.
+ It can be useful to apply certain access restrictions based on where the
+ client comes from (eg: require auth or https for remote machines). Please
+ note that the check involves a few system calls, so it's better to do it only
+ once per connection.
+
src_kbytes_in([]) : integer
Returns the total amount of data received from the incoming connection's
source address in the current proxy's stick-table or in the designated
diff --git a/include/common/standard.h b/include/common/standard.h
index 63f034525..5afaad20f 100644
--- a/include/common/standard.h
+++ b/include/common/standard.h
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#ifndef LLONG_MAX
@@ -358,6 +359,17 @@ int addr_to_str(struct sockaddr_storage *addr, char *str, int size);
*/
int port_to_str(struct sockaddr_storage *addr, char *str, int size);
+/* check if the given address is local to the system or not. It will return
+ * -1 when it's not possible to know, 0 when the address is not local, 1 when
+ * it is. We don't want to iterate over all interfaces for this (and it is not
+ * portable). So instead we try to bind in UDP to this address on a free non
+ * privileged port and to connect to the same address, port 0 (connect doesn't
+ * care). If it succeeds, we own the address. Note that non-inet addresses are
+ * considered local since they're most likely AF_UNIX.
+ */
+int addr_is_local(const struct netns_entry *ns,
+ const struct sockaddr_storage *orig);
+
/* will try to encode the string replacing all characters tagged in
*