Mark Bergsma has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/81244


Change subject: Initial version of PROXY support for Varnish
......................................................................

Initial version of PROXY support for Varnish

Change-Id: I325ea40c1777ffc48ec7ca6f4b92834812b626ea
---
M bin/varnishd/Makefile.am
M bin/varnishd/Makefile.in
M bin/varnishd/cache.h
M bin/varnishd/cache_acceptor.c
M bin/varnishd/cache_center.c
M bin/varnishd/cache_vrt_var.c
M bin/varnishd/heritage.h
M bin/varnishd/mgt_child.c
M bin/varnishd/mgt_param.c
A bin/varnishd/proxy_proto.c
M include/vrt_obj.h
M include/vss.h
M lib/libvarnish/vss.c
M lib/libvcl/generate.py
M lib/libvcl/vcc_fixed_token.c
M lib/libvcl/vcc_obj.c
16 files changed, 430 insertions(+), 8 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/debs/varnish 
refs/changes/44/81244/1

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index bfeb6b9..50e92ea 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -61,6 +61,7 @@
        mgt_sandbox_solaris.c \
        mgt_shmem.c \
        mgt_vcc.c \
+       proxy_proto.c \
        rfc2616.c \
        stevedore.c \
        storage_file.c \
diff --git a/bin/varnishd/Makefile.in b/bin/varnishd/Makefile.in
index 0dda608..e9db4b0 100644
--- a/bin/varnishd/Makefile.in
+++ b/bin/varnishd/Makefile.in
@@ -92,8 +92,8 @@
        varnishd-mgt_sandbox.$(OBJEXT) \
        varnishd-mgt_sandbox_solaris.$(OBJEXT) \
        varnishd-mgt_shmem.$(OBJEXT) varnishd-mgt_vcc.$(OBJEXT) \
-       varnishd-rfc2616.$(OBJEXT) varnishd-stevedore.$(OBJEXT) \
-       varnishd-storage_file.$(OBJEXT) \
+       varnishd-proxy_proto.$(OBJEXT) varnishd-rfc2616.$(OBJEXT) \
+       varnishd-stevedore.$(OBJEXT) varnishd-storage_file.$(OBJEXT) \
        varnishd-storage_malloc.$(OBJEXT) \
        varnishd-storage_persistent.$(OBJEXT) \
        varnishd-storage_persistent_mgt.$(OBJEXT) \
@@ -366,6 +366,7 @@
        mgt_sandbox_solaris.c \
        mgt_shmem.c \
        mgt_vcc.c \
+       proxy_proto.c \
        rfc2616.c \
        stevedore.c \
        storage_file.c \
@@ -556,6 +557,7 @@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/varnishd-mgt_sandbox_solaris.Po@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/varnishd-mgt_shmem.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varnishd-mgt_vcc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/varnishd-proxy_proto.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varnishd-rfc2616.Po@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/varnishd-stevedore.Po@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/varnishd-stevedore_utils.Po@am__quote@
@@ -1305,6 +1307,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -c -o 
varnishd-mgt_vcc.obj `if test -f 'mgt_vcc.c'; then $(CYGPATH_W) 'mgt_vcc.c'; 
else $(CYGPATH_W) '$(srcdir)/mgt_vcc.c'; fi`
 
+varnishd-proxy_proto.o: proxy_proto.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -MT 
varnishd-proxy_proto.o -MD -MP -MF $(DEPDIR)/varnishd-proxy_proto.Tpo -c -o 
varnishd-proxy_proto.o `test -f 'proxy_proto.c' || echo 
'$(srcdir)/'`proxy_proto.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/varnishd-proxy_proto.Tpo 
$(DEPDIR)/varnishd-proxy_proto.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='proxy_proto.c' 
object='varnishd-proxy_proto.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -c -o 
varnishd-proxy_proto.o `test -f 'proxy_proto.c' || echo 
'$(srcdir)/'`proxy_proto.c
+
+varnishd-proxy_proto.obj: proxy_proto.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -MT 
varnishd-proxy_proto.obj -MD -MP -MF $(DEPDIR)/varnishd-proxy_proto.Tpo -c -o 
varnishd-proxy_proto.obj `if test -f 'proxy_proto.c'; then $(CYGPATH_W) 
'proxy_proto.c'; else $(CYGPATH_W) '$(srcdir)/proxy_proto.c'; fi`
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/varnishd-proxy_proto.Tpo 
$(DEPDIR)/varnishd-proxy_proto.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='proxy_proto.c' 
object='varnishd-proxy_proto.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -c -o 
varnishd-proxy_proto.obj `if test -f 'proxy_proto.c'; then $(CYGPATH_W) 
'proxy_proto.c'; else $(CYGPATH_W) '$(srcdir)/proxy_proto.c'; fi`
+
 varnishd-rfc2616.o: rfc2616.c
 @am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(varnishd_CFLAGS) $(CFLAGS) -MT varnishd-rfc2616.o 
-MD -MP -MF $(DEPDIR)/varnishd-rfc2616.Tpo -c -o varnishd-rfc2616.o `test -f 
'rfc2616.c' || echo '$(srcdir)/'`rfc2616.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/varnishd-rfc2616.Tpo 
$(DEPDIR)/varnishd-rfc2616.Po
diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index 0ad00d8..f98d5e2 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -563,6 +563,9 @@
        char                    *port;
        char                    *client_identity;
 
+       /* PROXY data */
+       struct proxy_state *ps;
+
        /* HTTP request */
        const char              *doclose;
        struct http             *http;
@@ -969,6 +972,19 @@
 void SMP_Init(void);
 void SMP_Ready(void);
 
+/* proxy_proto.c */
+struct proxy_state;
+
+struct proxy_state *Proxy_Init(struct sess *sp);
+void Proxy_Finish(struct sess *sp);
+int Proxy_Read(const struct sess *sp);
+int Proxy_Parse(struct sess *sp);
+unsigned Proxy_Valid(const struct sess *sp);
+struct sockaddr_storage *Proxy_Client_Address(const struct sess *sp);
+struct sockaddr_storage *Proxy_Server_Address(const struct sess *sp);
+int Proxy_Client_Port(const struct sess *sp);
+int Proxy_Server_Port(const struct sess *sp);
+
 /*
  * A normal pointer difference is signed, but we never want a negative value
  * so this little tool will make sure we don't get that.
diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c
index c513e1a..4557c38 100644
--- a/bin/varnishd/cache_acceptor.c
+++ b/bin/varnishd/cache_acceptor.c
@@ -429,7 +429,7 @@
                if (ls->sock < 0)
                        continue;
                VTCP_myname(ls->sock, h, sizeof h, p, sizeof p);
-               VCLI_Out(cli, "%s %s\n", h, p);
+               VCLI_Out(cli, "%s %s %d\n", h, p, ls->proxy_port);
        }
 }
 
diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c
index 61d3fb4..e3b9b8e 100644
--- a/bin/varnishd/cache_center.c
+++ b/bin/varnishd/cache_center.c
@@ -1130,7 +1130,6 @@
 static int
 cnt_first(struct sess *sp)
 {
-
        /*
         * XXX: If we don't have acceptfilters we are somewhat subject
         * XXX: to DoS'ing here.  One remedy would be to set a shorter
@@ -1140,8 +1139,24 @@
 
        assert(sp->xid == 0);
        assert(sp->restarts == 0);
+
        VCA_Prep(sp);
 
+       /* Process the PROXY protocol */
+       if (sp->mylsock->proxy_port) {
+               AZ(sp->ps);
+               if (Proxy_Init(sp) == NULL
+                       || Proxy_Read(sp) < 0
+                       || Proxy_Parse(sp) < 0) {
+                       vca_close_session(sp, "PROXY protocol error");
+                       sp->step = STP_DONE;
+                       if (sp->ps != NULL)
+                               Proxy_Finish(sp);
+                       return (0);
+               }
+               Proxy_Finish(sp);
+       }
+
        /* Record the session watermark */
        sp->ws_ses = WS_Snapshot(sp->ws);
 
diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c
index fa65d84..bf96e28 100644
--- a/bin/varnishd/cache_vrt_var.c
+++ b/bin/varnishd/cache_vrt_var.c
@@ -377,6 +377,41 @@
        return (sp->restarts);
 }
 
+unsigned
+VRT_r_req_proxy(const struct sess *sp)
+{
+
+       return (Proxy_Valid(sp));
+}
+
+struct sockaddr_storage *
+VRT_r_req_proxy_client_ip(const struct sess *sp)
+{
+
+       return (Proxy_Client_Address(sp));
+}
+
+int
+VRT_r_req_proxy_client_port(const struct sess *sp)
+{
+
+       return (Proxy_Client_Port(sp));
+}
+
+struct sockaddr_storage *
+VRT_r_req_proxy_server_ip(const struct sess *sp)
+{
+
+       return (Proxy_Server_Address(sp));
+}
+
+int
+VRT_r_req_proxy_server_port(const struct sess *sp)
+{
+
+       return (Proxy_Server_Port(sp));
+}
+
 /*--------------------------------------------------------------------
  * NB: TTL is relative to when object was created, whereas grace and
  * keep are relative to ttl.
diff --git a/bin/varnishd/heritage.h b/bin/varnishd/heritage.h
index 66d2a05..4e6b956 100644
--- a/bin/varnishd/heritage.h
+++ b/bin/varnishd/heritage.h
@@ -39,6 +39,7 @@
        int                             sock;
        char                            *name;
        struct vss_addr                 *addr;
+       int                             proxy_port;
 };
 
 VTAILQ_HEAD(listen_sock_head, listen_sock);
@@ -137,6 +138,10 @@
        /* Listen depth */
        unsigned                listen_depth;
 
+       /* PROXY protocol */
+       unsigned                proxy_protocol_port;
+       unsigned                proxy_protocol_timeout;
+
        /* CLI related */
        unsigned                cli_timeout;
        unsigned                ping_interval;
diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c
index ee74452..10e60fa 100644
--- a/bin/varnishd/mgt_child.c
+++ b/bin/varnishd/mgt_child.c
@@ -236,6 +236,9 @@
 
                mgt_child_inherit(ls->sock, "sock");
 
+               if (VTCP_port(VSS_sockaddr(ls->addr)) == 
params->proxy_protocol_port)
+                       ls->proxy_port = 1;
+
                /*
                 * Set nonblocking mode to avoid a race where a client
                 * closes before we call accept(2) and nobody else are in
diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c
index 5687766..29710df 100644
--- a/bin/varnishd/mgt_param.c
+++ b/bin/varnishd/mgt_param.c
@@ -391,6 +391,7 @@
                        ls->addr = ta[j];
                        ls->name = strdup(av[i]);
                        AN(ls->name);
+                       ls->proxy_port = 0;
                        VTAILQ_INSERT_TAIL(&lsh, ls, list);
                }
                free(ta);
@@ -990,6 +991,19 @@
                "content.\n",
                EXPERIMENTAL,
                "256", "kilobytes" },
+       { "proxy_protocol_port", tweak_uint, &master.proxy_protocol_port,
+               0, 65535,
+               "TCP listen ports which should process the PROXY protocol. "
+               "On these TCP ports, Varnish requires the PROXY protocol "
+               "header to be sent before the first HTTP request.\n",
+               MUST_RESTART,
+               "0", "" },
+       { "proxy_protocol_timeout", tweak_uint,
+               &master.proxy_protocol_timeout, 0, UINT_MAX,
+               "The timeout for the workerthread waiting for the PROXY"
+               "protocol header to be received.\n",
+               0,
+               "500", "ms" },
        { NULL, NULL, NULL }
 };
 
diff --git a/bin/varnishd/proxy_proto.c b/bin/varnishd/proxy_proto.c
new file mode 100644
index 0000000..6f03cd2
--- /dev/null
+++ b/bin/varnishd/proxy_proto.c
@@ -0,0 +1,226 @@
+/*-
+ * Copyright (c) 2013 Wikimedia Foundation
+ * All rights reserved.
+ *
+ * Author: Mark Bergsma <m...@wikimedia.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * PROXY protocol handling
+ */
+
+#include <string.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "cache.h"
+
+const char v2sig[13] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02";
+
+struct proxy_v2 {
+       struct {
+               uint8_t sig[12];
+               uint8_t ver;
+               uint8_t cmd;
+               uint8_t fam;
+               uint8_t len;
+       } hdr;
+       union {
+               struct { /* for TCP/UDP over IPv4, len = 12 */
+                       uint32_t src_addr;
+                       uint32_t dst_addr;
+                       uint16_t src_port;
+                       uint16_t dst_port;
+               } ip4;
+               struct { /* for TCP/UDP over IPv6, len = 36 */
+                       uint8_t src_addr[16];
+                       uint8_t dst_addr[16];
+                       uint16_t src_port;
+                       uint16_t dst_port;
+               } ip6;
+       } addr;
+};
+
+struct proxy_state {
+       unsigned                magic;
+#define PROXY_STATE_MAGIC              0xE3D85857
+       int valid;
+       socklen_t client_addr_len;
+       socklen_t server_addr_len;
+       struct sockaddr_storage client_addr;
+       struct sockaddr_storage server_addr;
+
+       struct proxy_v2 *proxy_hdr;
+};
+
+struct proxy_state *
+Proxy_Init(struct sess *sp) {
+       struct proxy_state *ps;
+
+       ps = (struct proxy_state *)WS_Alloc(sp->ws, sizeof *ps);
+       if (ps == NULL)
+               return (NULL);
+       memset(ps, 0, sizeof *ps);
+       ps->magic = PROXY_STATE_MAGIC;
+       if (WS_Reserve(sp->ws, PRNDUP(sizeof(struct proxy_v2))) < sizeof(struct 
proxy_v2)) {
+               WS_Reset(sp->ws, (char *)ps);
+               return (NULL);
+       }
+       ps->proxy_hdr = (struct proxy_v2 *)sp->ws->f;
+       sp->ps = ps;
+       return (ps);
+}
+
+void
+Proxy_Finish(struct sess *sp) {
+       CHECK_OBJ_NOTNULL(sp->ps, PROXY_STATE_MAGIC);
+       if (sp->ps->proxy_hdr) {
+               WS_Release(sp->ws, 0);
+               sp->ps->proxy_hdr = NULL;
+       }
+}
+
+/*--------------------------------------------------------------------
+ * Read PROXY protocol header
+ * Returns:
+ *     -1 error, disconnect
+ *     >0 proxy header received, return number of bytes read
+ */
+int
+Proxy_Read(const struct sess *sp) {
+       struct proxy_v2 *phdr;
+       struct pollfd pfd[1];
+       int msgsize;
+
+       CHECK_OBJ_NOTNULL(sp->ps, PROXY_STATE_MAGIC);
+       phdr = sp->ps->proxy_hdr;
+
+       /* Wait until we have data */
+       if (params->proxy_protocol_timeout > 0) {
+               pfd[0].fd = sp->fd;
+               pfd[0].events = POLLIN;
+               pfd[0].revents = 0;
+               if (poll(pfd, 1, params->proxy_protocol_timeout) != 1)
+                       return (-1);
+       }
+
+       /* Read the PROXY header */
+       if (recv(sp->fd, phdr, sizeof *phdr, MSG_PEEK) == sizeof *phdr
+               && memcmp(phdr->hdr.sig, v2sig, sizeof v2sig) == 0
+               && phdr->hdr.len <= sizeof phdr->addr) {
+               msgsize = sizeof phdr->hdr + phdr->hdr.len;
+               assert(msgsize <= sizeof *phdr);
+               if (read(sp->fd, phdr, msgsize) == msgsize) /* Read appropriate 
nr of bytes from the socket */
+                       return (msgsize);
+       }
+       return (-1);
+}
+
+int
+Proxy_Parse(struct sess *sp) {
+       struct proxy_v2 *phdr;
+
+       CHECK_OBJ_NOTNULL(sp->ps, PROXY_STATE_MAGIC);
+       phdr = sp->ps->proxy_hdr;
+
+       switch (phdr->hdr.cmd) {
+       case 0x01: /* PROXY command */
+               switch (phdr->hdr.fam) {
+               case 0x11: /* TCPv4 */
+                       if (phdr->hdr.len < sizeof phdr->addr.ip4)
+                               return (-1);
+                       sp->ps->client_addr_len = sp->ps->server_addr_len = 
sizeof(struct sockaddr_in);
+                       ((struct sockaddr_in *) 
&sp->ps->client_addr)->sin_family = AF_INET;
+                       ((struct sockaddr_in *) 
&sp->ps->client_addr)->sin_addr.s_addr =
+                                       phdr->addr.ip4.src_addr;
+                       ((struct sockaddr_in *) &sp->ps->client_addr)->sin_port 
= phdr->addr.ip4.src_port;
+                       ((struct sockaddr_in *) 
&sp->ps->server_addr)->sin_family = AF_INET;
+                       ((struct sockaddr_in *) 
&sp->ps->server_addr)->sin_addr.s_addr =
+                                       phdr->addr.ip4.dst_addr;
+                       ((struct sockaddr_in *) &sp->ps->server_addr)->sin_port 
= phdr->addr.ip4.dst_port;
+                       sp->ps->valid = 1;
+                       break;
+               case 0x21: /* TCPv6 */
+                       if (phdr->hdr.len < sizeof phdr->addr.ip6)
+                               return (-1);
+                       sp->ps->client_addr_len = sp->ps->server_addr_len = 
sizeof(struct sockaddr_in6);
+                       ((struct sockaddr_in6 *) 
&sp->ps->client_addr)->sin6_family = AF_INET6;
+                       memcpy(&((struct sockaddr_in6 *) 
&sp->ps->client_addr)->sin6_addr,
+                                       phdr->addr.ip6.src_addr, 16);
+                       ((struct sockaddr_in6 *) 
&sp->ps->client_addr)->sin6_port =
+                                       phdr->addr.ip6.src_port;
+                       ((struct sockaddr_in6 *) 
&sp->ps->server_addr)->sin6_family = AF_INET6;
+                       memcpy(&((struct sockaddr_in6 *) 
&sp->ps->server_addr)->sin6_addr,
+                                       phdr->addr.ip6.dst_addr, 16);
+                       ((struct sockaddr_in6 *) 
&sp->ps->server_addr)->sin6_port =
+                                       phdr->addr.ip6.dst_port;
+                       sp->ps->valid = 1;
+                       break;
+               }
+               /* Error or unsupported protocol, keep local connection address 
*/
+               break;
+       case 0x00: /* LOCAL command */
+               /* Use local connection address for LOCAL */
+               sp->ps->client_addr_len = sp->sockaddrlen;
+               sp->ps->server_addr_len = sp->mysockaddrlen;
+               memcpy(&sp->ps->client_addr, sp->sockaddr, sizeof(struct 
sockaddr_storage));
+               memcpy(&sp->ps->server_addr, sp->mysockaddr, sizeof(struct 
sockaddr_storage));
+               sp->ps->valid = 1;
+               break;
+       }
+       return (sp->ps->valid ? 0 : -1);
+}
+
+inline struct proxy_state *
+Proxy_State(const struct sess *sp) {
+       if (sp->ps == NULL)
+               return (NULL);
+
+       CHECK_OBJ_NOTNULL(sp->ps, PROXY_STATE_MAGIC);
+       return (sp->ps);
+}
+
+/* --------------------------------------------------------------------------
+ */
+
+unsigned Proxy_Valid(const struct sess *sp) {
+       return (sp->ps != NULL && Proxy_State(sp)->valid);
+}
+
+struct sockaddr_storage *
+Proxy_Client_Address(const struct sess *sp) {
+       return (Proxy_Valid(sp) ? &Proxy_State(sp)->client_addr : sp->sockaddr);
+}
+
+struct sockaddr_storage *
+Proxy_Server_Address(const struct sess *sp) {
+       return (Proxy_Valid(sp) ? &Proxy_State(sp)->server_addr : 
sp->mysockaddr);
+}
+
+int Proxy_Client_Port(const struct sess *sp) {
+       return (VTCP_port(Proxy_Valid(sp) ? &Proxy_State(sp)->client_addr : 
sp->sockaddr));
+}
+
+int Proxy_Server_Port(const struct sess *sp) {
+       return (VTCP_port(Proxy_Valid(sp) ? &Proxy_State(sp)->server_addr : 
sp->mysockaddr));
+}
diff --git a/include/vrt_obj.h b/include/vrt_obj.h
index 12d0698..56d8bda 100644
--- a/include/vrt_obj.h
+++ b/include/vrt_obj.h
@@ -35,6 +35,11 @@
 void VRT_l_req_hash_ignore_busy(struct sess *, unsigned);
 unsigned VRT_r_req_hash_always_miss(struct sess *);
 void VRT_l_req_hash_always_miss(struct sess *, unsigned);
+unsigned VRT_r_req_proxy(const struct sess *);
+struct sockaddr_storage * VRT_r_req_proxy_client_ip(const struct sess *);
+int VRT_r_req_proxy_client_port(const struct sess *);
+struct sockaddr_storage * VRT_r_req_proxy_server_ip(const struct sess *);
+int VRT_r_req_proxy_server_port(const struct sess *);
 const char * VRT_r_bereq_request(const struct sess *);
 void VRT_l_bereq_request(const struct sess *, const char *, ...);
 const char * VRT_r_bereq_url(const struct sess *);
diff --git a/include/vss.h b/include/vss.h
index d98aa1d..2e779e1 100644
--- a/include/vss.h
+++ b/include/vss.h
@@ -35,3 +35,4 @@
 int VSS_listen(const struct vss_addr *addr, int depth);
 int VSS_connect(const struct vss_addr *addr, int nonblock);
 int VSS_open(const char *str, double tmo);
+const struct sockaddr_storage* VSS_sockaddr(const struct vss_addr *va);
diff --git a/lib/libvarnish/vss.c b/lib/libvarnish/vss.c
index f902023..4d7e581 100644
--- a/lib/libvarnish/vss.c
+++ b/lib/libvarnish/vss.c
@@ -307,3 +307,8 @@
        free(vaddr);
        return (retval);
 }
+
+const struct sockaddr_storage *
+VSS_sockaddr(const struct vss_addr *va) {
+       return (&va->va_addr);
+}
diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py
index 4d8f62a..09813ad 100755
--- a/lib/libvcl/generate.py
+++ b/lib/libvcl/generate.py
@@ -235,6 +235,36 @@
                ( 'recv',),
                'struct sess *'
        ),
+       ('req.proxy',
+               'BOOL',
+               ( 'proc',),
+               ( ),
+               'const struct sess *'
+       ),
+       ('req.proxy.client.ip',
+               'IP',
+               ( 'proc',),
+               ( ),
+               'const struct sess *'
+       ),
+       ('req.proxy.client.port',
+               'INT',
+               ( 'proc',),
+               ( ),
+               'const struct sess *'
+       ),
+       ('req.proxy.server.ip',
+               'IP',
+               ( 'proc',),
+               ( ),
+               'const struct sess *'
+       ),
+       ('req.proxy.server.port',
+               'INT',
+               ( 'proc',),
+               ( ),
+               'const struct sess *'
+       ),
        ('bereq.request',
                'STRING',
                ( 'pipe', 'pass', 'miss', 'fetch',),
diff --git a/lib/libvcl/vcc_fixed_token.c b/lib/libvcl/vcc_fixed_token.c
index c8a48d5..b649011 100644
--- a/lib/libvcl/vcc_fixed_token.c
+++ b/lib/libvcl/vcc_fixed_token.c
@@ -155,7 +155,7 @@
 vcl_output_lang_h(struct vsb *sb)
 {
 
-       /* ../include/vcl.h */
+       /* ../../include/vcl.h */
 
        VSB_cat(sb, "/*\n * NB:  This file is machine generated, DO "
            "NOT EDIT!\n *\n * Edit and run generate.py instead\n"
@@ -189,7 +189,7 @@
            "\tvcl_func_f\t*error_func;\n\tvcl_func_f\t*init_func;\n"
            "\tvcl_func_f\t*fini_func;\n\n};\n" );
 
-       /* ../include/vrt.h */
+       /* ../../include/vrt.h */
 
        VSB_cat(sb, "/*-\n * Copyright (c) 2006 Verdens Gang AS\n"
            " * Copyright (c) 2006-2010 Varnish Software AS\n * All rights "
@@ -303,7 +303,7 @@
            "ing(const struct sess *sp, const char *p, ...);\n"
        );
 
-       /* ../include/vrt_obj.h */
+       /* ../../include/vrt_obj.h */
 
        VSB_cat(sb, "/*\n * NB:  This file is machine generated, DO "
            "NOT EDIT!\n *\n * Edit and run generate.py instead\n"
@@ -334,7 +334,12 @@
            "gnore_busy(struct sess *);\nvoid VRT_l_req_hash_ignore_busy(stru"
            "ct sess *, unsigned);\nunsigned VRT_r_req_hash_always_miss(struc"
            "t sess *);\nvoid VRT_l_req_hash_always_miss(struct sess *, "
-           "unsigned);\nconst char * VRT_r_bereq_request(const struct "
+           "unsigned);\nunsigned VRT_r_req_proxy(const struct sess *);\n"
+           "struct sockaddr_storage * VRT_r_req_proxy_client_ip(const "
+           "struct sess *);\nint VRT_r_req_proxy_client_port(const struct "
+           "sess *);\nstruct sockaddr_storage * VRT_r_req_proxy_server_ip(co"
+           "nst struct sess *);\nint VRT_r_req_proxy_server_port(const "
+           "struct sess *);\nconst char * VRT_r_bereq_request(const struct "
            "sess *);\nvoid VRT_l_bereq_request(const struct sess *, const "
            "char *, ...);\nconst char * VRT_r_bereq_url(const struct sess "
            "*);\nvoid VRT_l_bereq_url(const struct sess *, const char "
diff --git a/lib/libvcl/vcc_obj.c b/lib/libvcl/vcc_obj.c
index 76e812b..6dc7b51 100644
--- a/lib/libvcl/vcc_obj.c
+++ b/lib/libvcl/vcc_obj.c
@@ -219,6 +219,51 @@
            VCL_MET_RECV,
            0,
        },
+       { "req.proxy", BOOL, 9,
+           "VRT_r_req_proxy(sp)",
+           VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
+            | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
+            | VCL_MET_ERROR,
+           NULL,       /* No writes allowed */
+           0,
+           0,
+       },
+       { "req.proxy.client.ip", IP, 19,
+           "VRT_r_req_proxy_client_ip(sp)",
+           VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
+            | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
+            | VCL_MET_ERROR,
+           NULL,       /* No writes allowed */
+           0,
+           0,
+       },
+       { "req.proxy.client.port", INT, 21,
+           "VRT_r_req_proxy_client_port(sp)",
+           VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
+            | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
+            | VCL_MET_ERROR,
+           NULL,       /* No writes allowed */
+           0,
+           0,
+       },
+       { "req.proxy.server.ip", IP, 19,
+           "VRT_r_req_proxy_server_ip(sp)",
+           VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
+            | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
+            | VCL_MET_ERROR,
+           NULL,       /* No writes allowed */
+           0,
+           0,
+       },
+       { "req.proxy.server.port", INT, 21,
+           "VRT_r_req_proxy_server_port(sp)",
+           VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
+            | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
+            | VCL_MET_ERROR,
+           NULL,       /* No writes allowed */
+           0,
+           0,
+       },
        { "bereq.request", STRING, 13,
            "VRT_r_bereq_request(sp)",
            VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_MISS | VCL_MET_FETCH,

-- 
To view, visit https://gerrit.wikimedia.org/r/81244
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I325ea40c1777ffc48ec7ca6f4b92834812b626ea
Gerrit-PatchSet: 1
Gerrit-Project: operations/debs/varnish
Gerrit-Branch: patches/proxy-support
Gerrit-Owner: Mark Bergsma <m...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to