]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: introduce "struct conn_src" for servers and proxies
authorWilly Tarreau <w@1wt.eu>
Sat, 8 Dec 2012 21:29:20 +0000 (22:29 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 9 Dec 2012 09:04:39 +0000 (10:04 +0100)
Both servers and proxies share a common set of parameters for outgoing
connections, and since they're not stored in a similar structure, a lot
of code is duplicated in the connection setup, which is one sensible
area.

Let's first define a common struct for these settings and make use of it.
Next patches will de-duplicate code.

This change also fixes a build breakage that happens when USE_LINUX_TPROXY
is not set but USE_CTTPROXY is set, which seem to be very unlikely
considering that the issue was introduced almost 2 years ago an never
reported.

include/types/connection.h
include/types/proxy.h
include/types/server.h
src/backend.c
src/cfgparse.c
src/proto_tcp.c

index b2396c44d2e43c7fd801fc56eef2093f9db0c12b..255811ca647ebb4e44f7dda40488d1ed6a056eff 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <types/listener.h>
 #include <types/obj_type.h>
+#include <types/port_range.h>
 #include <types/protocol.h>
 
 /* referenced below */
@@ -162,6 +163,19 @@ enum {
        CO_ER_SSL_NO_TARGET,    /* unkonwn target (not client nor server) */
 };
 
+/* source address settings for outgoing connections */
+enum {
+       /* Tproxy exclusive values from 0 to 7 */
+       CO_SRC_TPROXY_ADDR = 0x0001,    /* bind to this non-local address when connecting */
+       CO_SRC_TPROXY_CIP  = 0x0002,    /* bind to the client's IP address when connecting */
+       CO_SRC_TPROXY_CLI  = 0x0003,    /* bind to the client's IP+port when connecting */
+       CO_SRC_TPROXY_DYN  = 0x0004,    /* bind to a dynamically computed non-local address */
+       CO_SRC_TPROXY_MASK = 0x0007,    /* bind to a non-local address when connecting */
+
+       CO_SRC_BIND        = 0x0008,    /* bind to a specific source address when connecting */
+};
+
+
 /* xprt_ops describes transport-layer operations for a connection. They
  * generally run over a socket-based control layer, but not always. Some
  * of them are used for data transfer with the upper layer (rcv_*, snd_*)
@@ -195,6 +209,24 @@ struct data_cb {
        int  (*init)(struct connection *conn);  /* data-layer initialization */
 };
 
+/* a connection source profile defines all the parameters needed to properly
+ * bind an outgoing connection for a server or proxy.
+ */
+
+struct conn_src {
+       unsigned int opts;                   /* CO_SRC_* */
+       int iface_len;                       /* bind interface name length */
+       char *iface_name;                    /* bind interface name or NULL */
+       struct port_range *sport_range;      /* optional per-server TCP source ports */
+       struct sockaddr_storage source_addr; /* the address to which we want to bind for connect() */
+#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
+       struct sockaddr_storage tproxy_addr; /* non-local address we want to bind to for connect() */
+       char *bind_hdr_name;                 /* bind to this header name if defined */
+       int bind_hdr_len;                    /* length of the name of the header above */
+       int bind_hdr_occ;                    /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */
+#endif
+};
+
 /* This structure describes a connection with its methods and data.
  * A connection may be performed to proxy or server via a local or remote
  * socket, and can also be made to an internal applet. It can support
index 5d99423abc11dcc13b5daa24e0bcacdcb904f4c3..ceb14d1fdcaffcece73b5f987b09c839f6f5a954 100644 (file)
@@ -78,7 +78,7 @@ enum {
 #define PR_O_DISPATCH   0x00000040      /* use dispatch mode */
 #define PR_O_KEEPALIVE  0x00000080      /* follow keep-alive sessions */
 #define PR_O_FWDFOR     0x00000100      /* conditionally insert x-forwarded-for with client address */
-#define PR_O_BIND_SRC   0x00000200      /* bind to a specific source address when connect()ing */
+/* unused: 0x00000200 */
 #define PR_O_NULLNOLOG  0x00000400      /* a connect without request will not be logged */
 /* unused: 0x0800, 0x1000 */
 #define PR_O_FF_ALWAYS  0x00002000      /* always set x-forwarded-for */
@@ -93,13 +93,7 @@ enum {
 #define PR_O_TCP_NOLING 0x00400000      /* disable lingering on client and server connections */
 #define PR_O_ABRT_CLOSE 0x00800000      /* immediately abort request when client closes */
 
-/* TPXY: exclusive values */
-#define PR_O_TPXY_ADDR  0x01000000     /* bind to this non-local address when connect()ing */
-#define PR_O_TPXY_CIP   0x02000000     /* bind to the client's IP address when connect()ing */
-#define PR_O_TPXY_CLI   0x03000000     /* bind to the client's IP+port when connect()ing */
-#define PR_O_TPXY_DYN   0x04000000     /* bind to a dynamically computed non-local address */
-#define PR_O_TPXY_MASK  0x07000000     /* bind to a non-local address when connect()ing */
-
+/* unused: 0x01000000, 0x02000000, 0x04000000 */
 #define PR_O_SERVER_CLO 0x08000000     /* option http-server-close */
 #define PR_O_CONTSTATS 0x10000000      /* continous counters */
 #define PR_O_HTTP_PROXY 0x20000000     /* Enable session to use HTTP proxy operations */
@@ -303,9 +297,8 @@ struct proxy {
 
        int conn_retries;                       /* maximum number of connect retries */
        int cap;                                /* supported capabilities (PR_CAP_*) */
-       int iface_len;                          /* bind interface name length */
-       char *iface_name;                       /* bind interface name or NULL */
        int (*accept)(struct session *s);       /* application layer's accept() */
+       struct conn_src conn_src;               /* connection source settings */
        struct proxy *next;
        struct list logsrvs;
        struct list logformat;                  /* log_format linked list */
@@ -340,13 +333,6 @@ struct proxy {
 
        /* warning: these structs are huge, keep them at the bottom */
        struct sockaddr_storage dispatch_addr;  /* the default address to connect to */
-       struct sockaddr_storage source_addr;    /* the address to which we want to bind for connect() */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-       struct sockaddr_storage tproxy_addr;    /* non-local address we want to bind to for connect() */
-       char *bind_hdr_name;                    /* bind to this header name if defined */
-       int bind_hdr_len;                       /* length of the name of the header above */
-       int bind_hdr_occ;                       /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */
-#endif
        struct error_snapshot invalid_req, invalid_rep; /* captures of last errors */
 
        /* used only during configuration parsing */
index ac7ab7bacd9cb88115fe8c868a789432f721c89e..b58a06207b5c90c2e9b11a9a623dafcf1238e411 100644 (file)
@@ -37,7 +37,6 @@
 #include <types/counters.h>
 #include <types/freq_ctr.h>
 #include <types/obj_type.h>
-#include <types/port_range.h>
 #include <types/proxy.h>
 #include <types/queue.h>
 #include <types/task.h>
 #define SRV_RUNNING    0x0001  /* the server is UP */
 #define SRV_BACKUP     0x0002  /* this server is a backup server */
 #define SRV_MAPPORTS   0x0004  /* this server uses mapped ports */
-#define SRV_BIND_SRC   0x0008  /* this server uses a specific source address */
+/* unused: 0x0008 */
 #define SRV_CHECKED    0x0010  /* this server needs to be checked */
 #define SRV_GOINGDOWN  0x0020  /* this server says that it's going down (404) */
 #define SRV_WARMINGUP  0x0040  /* this server is warming up after a failure */
 #define SRV_MAINTAIN   0x0080  /* this server is in maintenance mode */
-#define SRV_TPROXY_ADDR        0x0100  /* bind to this non-local address to reach this server */
-#define SRV_TPROXY_CIP 0x0200  /* bind to the client's IP address to reach this server */
-#define SRV_TPROXY_CLI 0x0300  /* bind to the client's IP+port to reach this server */
-#define SRV_TPROXY_DYN 0x0400  /* bind to a dynamically computed non-local address */
-#define SRV_TPROXY_MASK        0x0700  /* bind to a non-local address to reach this server */
+/* unused: 0x0100, 0x0200, 0x0400 */
 #define SRV_SEND_PROXY 0x0800  /* this server talks the PROXY protocol */
 #define SRV_NON_STICK  0x1000  /* never add connections allocated to this server to a stick table */
 #define SRV_CHK_RUNNING 0x2000  /* a check is currently running on this server */
@@ -131,9 +126,7 @@ struct server {
        struct list actconns;                   /* active connections */
        struct task *warmup;                    /* the task dedicated to the warmup when slowstart is set */
 
-       int iface_len;                          /* bind interface name length */
-       char *iface_name;                       /* bind interface name or NULL */
-       struct port_range *sport_range;         /* optional per-server TCP source ports */
+       struct conn_src conn_src;               /* connection source settings */
 
        struct server *tracknext, *track;       /* next server in a tracking list, tracked server */
        char *trackit;                          /* temporary variable to make assignment deferrable */
@@ -163,13 +156,6 @@ struct server {
 
        /* warning, these structs are huge, keep them at the bottom */
        struct sockaddr_storage addr;           /* the address to connect to */
-       struct sockaddr_storage source_addr;    /* the address to which we want to bind for connect() */
-#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-       struct sockaddr_storage tproxy_addr;    /* non-local address we want to bind to for connect() */
-       char *bind_hdr_name;                    /* bind to this header name if defined */
-       int bind_hdr_len;                       /* length of the name of the header above */
-       int bind_hdr_occ;                       /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */
-#endif
        struct protocol *proto;                 /* server address protocol */
        struct xprt_ops *xprt;                  /* transport-layer operations */
        unsigned down_time;                     /* total time the server was down */
index 96545a9918d3bd4fa861d28035b0a995e98abbf7..f81b75f8d6677edb00e85d1a91eb697e4539833f 100644 (file)
@@ -885,18 +885,18 @@ static void assign_tproxy_address(struct session *s)
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
        struct server *srv = objt_server(s->target);
 
-       if (srv && srv->state & SRV_BIND_SRC) {
-               switch (srv->state & SRV_TPROXY_MASK) {
-               case SRV_TPROXY_ADDR:
-                       s->req->cons->conn->addr.from = srv->tproxy_addr;
+       if (srv && srv->conn_src.opts & CO_SRC_BIND) {
+               switch (srv->conn_src.opts & CO_SRC_TPROXY_MASK) {
+               case CO_SRC_TPROXY_ADDR:
+                       s->req->cons->conn->addr.from = srv->conn_src.tproxy_addr;
                        break;
-               case SRV_TPROXY_CLI:
-               case SRV_TPROXY_CIP:
+               case CO_SRC_TPROXY_CLI:
+               case CO_SRC_TPROXY_CIP:
                        /* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
                        s->req->cons->conn->addr.from = s->req->prod->conn->addr.from;
                        break;
-               case SRV_TPROXY_DYN:
-                       if (srv->bind_hdr_occ) {
+               case CO_SRC_TPROXY_DYN:
+                       if (srv->conn_src.bind_hdr_occ) {
                                char *vptr;
                                int vlen;
                                int rewind;
@@ -907,8 +907,8 @@ static void assign_tproxy_address(struct session *s)
                                ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr = 0;
 
                                b_rew(s->req->buf, rewind = s->req->buf->o);
-                               if (http_get_hdr(&s->txn.req, srv->bind_hdr_name, srv->bind_hdr_len,
-                                                &s->txn.hdr_idx, srv->bind_hdr_occ, NULL, &vptr, &vlen)) {
+                               if (http_get_hdr(&s->txn.req, srv->conn_src.bind_hdr_name, srv->conn_src.bind_hdr_len,
+                                                &s->txn.hdr_idx, srv->conn_src.bind_hdr_occ, NULL, &vptr, &vlen)) {
                                        ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr =
                                                htonl(inetaddr_host_lim(vptr, vptr + vlen));
                                }
@@ -919,18 +919,18 @@ static void assign_tproxy_address(struct session *s)
                        memset(&s->req->cons->conn->addr.from, 0, sizeof(s->req->cons->conn->addr.from));
                }
        }
-       else if (s->be->options & PR_O_BIND_SRC) {
-               switch (s->be->options & PR_O_TPXY_MASK) {
-               case PR_O_TPXY_ADDR:
-                       s->req->cons->conn->addr.from = s->be->tproxy_addr;
+       else if (s->be->conn_src.opts & CO_SRC_BIND) {
+               switch (s->be->conn_src.opts & CO_SRC_TPROXY_MASK) {
+               case CO_SRC_TPROXY_ADDR:
+                       s->req->cons->conn->addr.from = s->be->conn_src.tproxy_addr;
                        break;
-               case PR_O_TPXY_CLI:
-               case PR_O_TPXY_CIP:
+               case CO_SRC_TPROXY_CLI:
+               case CO_SRC_TPROXY_CIP:
                        /* FIXME: what can we do if the client connects in IPv6 or socket unix? */
                        s->req->cons->conn->addr.from = s->req->prod->conn->addr.from;
                        break;
-               case PR_O_TPXY_DYN:
-                       if (s->be->bind_hdr_occ) {
+               case CO_SRC_TPROXY_DYN:
+                       if (s->be->conn_src.bind_hdr_occ) {
                                char *vptr;
                                int vlen;
                                int rewind;
@@ -941,8 +941,8 @@ static void assign_tproxy_address(struct session *s)
                                ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr = 0;
 
                                b_rew(s->req->buf, rewind = s->req->buf->o);
-                               if (http_get_hdr(&s->txn.req, s->be->bind_hdr_name, s->be->bind_hdr_len,
-                                                &s->txn.hdr_idx, s->be->bind_hdr_occ, NULL, &vptr, &vlen)) {
+                               if (http_get_hdr(&s->txn.req, s->be->conn_src.bind_hdr_name, s->be->conn_src.bind_hdr_len,
+                                                &s->txn.hdr_idx, s->be->conn_src.bind_hdr_occ, NULL, &vptr, &vlen)) {
                                        ((struct sockaddr_in *)&s->req->cons->conn->addr.from)->sin_addr.s_addr =
                                                htonl(inetaddr_host_lim(vptr, vptr + vlen));
                                }
index f1cb96ef93a1db49907a3210963645701bfd3d0d..4e5963e42fe522fc84d78492b7ec4ad4ba859ba9 100644 (file)
@@ -1785,9 +1785,10 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        curproxy->hh_len  = defproxy.hh_len;
                        curproxy->hh_match_domain  = defproxy.hh_match_domain;
 
-                       if (defproxy.iface_name)
-                               curproxy->iface_name = strdup(defproxy.iface_name);
-                       curproxy->iface_len  = defproxy.iface_len;
+                       if (defproxy.conn_src.iface_name)
+                               curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
+                       curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
+                       curproxy->conn_src.opts = defproxy.conn_src.opts & ~CO_SRC_TPROXY_MASK;
                }
 
                if (curproxy->cap & PR_CAP_FE) {
@@ -1829,7 +1830,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        curproxy->timeout.httpreq = defproxy.timeout.httpreq;
                        curproxy->timeout.httpka = defproxy.timeout.httpka;
                        curproxy->timeout.tunnel = defproxy.timeout.tunnel;
-                       curproxy->source_addr = defproxy.source_addr;
+                       curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
                }
 
                curproxy->mode = defproxy.mode;
@@ -1877,7 +1878,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                free(defproxy.capture_name);
                free(defproxy.monitor_uri);
                free(defproxy.defbe.name);
-               free(defproxy.iface_name);
+               free(defproxy.conn_src.iface_name);
                free(defproxy.fwdfor_hdr_name);
                defproxy.fwdfor_hdr_len = 0;
                free(defproxy.orgto_hdr_name);
@@ -4519,14 +4520,14 @@ stats_error_parsing:
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
-                               newsrv->state |= SRV_BIND_SRC;
+                               newsrv->conn_src.opts |= CO_SRC_BIND;
                                sk = str2sa_range(args[cur_arg + 1], &port_low, &port_high);
                                if (!sk) {
                                        Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[cur_arg + 1]);
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
-                               newsrv->source_addr = *sk;
+                               newsrv->conn_src.source_addr = *sk;
 
                                if (port_low != port_high) {
                                        int i;
@@ -4538,9 +4539,9 @@ stats_error_parsing:
                                                err_code |= ERR_ALERT | ERR_FATAL;
                                                goto out;
                                        }
-                                       newsrv->sport_range = port_range_alloc_range(port_high - port_low + 1);
-                                       for (i = 0; i < newsrv->sport_range->size; i++)
-                                               newsrv->sport_range->ports[i] = port_low + i;
+                                       newsrv->conn_src.sport_range = port_range_alloc_range(port_high - port_low + 1);
+                                       for (i = 0; i < newsrv->conn_src.sport_range->size; i++)
+                                               newsrv->conn_src.sport_range->ports[i] = port_low + i;
                                }
 
                                cur_arg += 2;
@@ -4548,7 +4549,7 @@ stats_error_parsing:
                                        if (!strcmp(args[cur_arg], "usesrc")) {  /* address to use outside */
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
 #if !defined(CONFIG_HAP_LINUX_TPROXY)
-                                               if (newsrv->source_addr.sin_addr.s_addr == INADDR_ANY) {
+                                               if (!is_addr(&newsrv->conn_src.source_addr)) {
                                                        Alert("parsing [%s:%d] : '%s' requires an explicit '%s' address.\n",
                                                              file, linenum, "usesrc", "source");
                                                        err_code |= ERR_ALERT | ERR_FATAL;
@@ -4562,11 +4563,11 @@ stats_error_parsing:
                                                        goto out;
                                                }
                                                if (!strcmp(args[cur_arg + 1], "client")) {
-                                                       newsrv->state &= ~SRV_TPROXY_MASK;
-                                                       newsrv->state |= SRV_TPROXY_CLI;
+                                                       newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                                       newsrv->conn_src.opts |= CO_SRC_TPROXY_CLI;
                                                } else if (!strcmp(args[cur_arg + 1], "clientip")) {
-                                                       newsrv->state &= ~SRV_TPROXY_MASK;
-                                                       newsrv->state |= SRV_TPROXY_CIP;
+                                                       newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                                       newsrv->conn_src.opts |= CO_SRC_TPROXY_CIP;
                                                } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
                                                        char *name, *end;
 
@@ -4578,13 +4579,13 @@ stats_error_parsing:
                                                        while (*end && !isspace(*end) && *end != ',' && *end != ')')
                                                                end++;
 
-                                                       newsrv->state &= ~SRV_TPROXY_MASK;
-                                                       newsrv->state |= SRV_TPROXY_DYN;
-                                                       newsrv->bind_hdr_name = calloc(1, end - name + 1);
-                                                       newsrv->bind_hdr_len = end - name;
-                                                       memcpy(newsrv->bind_hdr_name, name, end - name);
-                                                       newsrv->bind_hdr_name[end-name] = '\0';
-                                                       newsrv->bind_hdr_occ = -1;
+                                                       newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                                       newsrv->conn_src.opts |= CO_SRC_TPROXY_DYN;
+                                                       newsrv->conn_src.bind_hdr_name = calloc(1, end - name + 1);
+                                                       newsrv->conn_src.bind_hdr_len = end - name;
+                                                       memcpy(newsrv->conn_src.bind_hdr_name, name, end - name);
+                                                       newsrv->conn_src.bind_hdr_name[end-name] = '\0';
+                                                       newsrv->conn_src.bind_hdr_occ = -1;
 
                                                        /* now look for an occurrence number */
                                                        while (isspace(*end))
@@ -4596,10 +4597,10 @@ stats_error_parsing:
                                                                        end++;
                                                                while (isdigit((int)*end))
                                                                        end++;
-                                                               newsrv->bind_hdr_occ = strl2ic(name, end-name);
+                                                               newsrv->conn_src.bind_hdr_occ = strl2ic(name, end-name);
                                                        }
 
-                                                       if (newsrv->bind_hdr_occ < -MAX_HDR_HISTORY) {
+                                                       if (newsrv->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
                                                                Alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
                                                                      " occurrences values smaller than %d.\n",
                                                                      file, linenum, MAX_HDR_HISTORY);
@@ -4613,8 +4614,8 @@ stats_error_parsing:
                                                                err_code |= ERR_ALERT | ERR_FATAL;
                                                                goto out;
                                                        }
-                                                       newsrv->tproxy_addr = *sk;
-                                                       newsrv->state |= SRV_TPROXY_ADDR;
+                                                       newsrv->conn_src.tproxy_addr = *sk;
+                                                       newsrv->conn_src.opts |= CO_SRC_TPROXY_ADDR;
                                                }
                                                global.last_checks |= LSTCHK_NETADM;
 #if !defined(CONFIG_HAP_LINUX_TPROXY)
@@ -4638,11 +4639,9 @@ stats_error_parsing:
                                                        err_code |= ERR_ALERT | ERR_FATAL;
                                                        goto out;
                                                }
-                                               if (newsrv->iface_name)
-                                                       free(newsrv->iface_name);
-
-                                               newsrv->iface_name = strdup(args[cur_arg + 1]);
-                                               newsrv->iface_len  = strlen(newsrv->iface_name);
+                                               free(newsrv->conn_src.iface_name);
+                                               newsrv->conn_src.iface_name = strdup(args[cur_arg + 1]);
+                                               newsrv->conn_src.iface_len  = strlen(newsrv->conn_src.iface_name);
                                                global.last_checks |= LSTCHK_NETADM;
 #else
                                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
@@ -4961,10 +4960,10 @@ stats_error_parsing:
                }
 
                /* we must first clear any optional default setting */  
-               curproxy->options &= ~PR_O_TPXY_MASK;
-               free(curproxy->iface_name);
-               curproxy->iface_name = NULL;
-               curproxy->iface_len = 0;
+               curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+               free(curproxy->conn_src.iface_name);
+               curproxy->conn_src.iface_name = NULL;
+               curproxy->conn_src.iface_len = 0;
 
                sk = str2sa(args[1]);
                if (!sk) {
@@ -4972,15 +4971,15 @@ stats_error_parsing:
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               curproxy->source_addr = *sk;
-               curproxy->options |= PR_O_BIND_SRC;
+               curproxy->conn_src.source_addr = *sk;
+               curproxy->conn_src.opts |= CO_SRC_BIND;
 
                cur_arg = 2;
                while (*(args[cur_arg])) {
                        if (!strcmp(args[cur_arg], "usesrc")) {  /* address to use outside */
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
 #if !defined(CONFIG_HAP_LINUX_TPROXY)
-                               if (curproxy->source_addr.sin_addr.s_addr == INADDR_ANY) {
+                               if (!is_addr(&curproxy->conn_src.source_addr)) {
                                        Alert("parsing [%s:%d] : '%s' requires an explicit 'source' address.\n",
                                              file, linenum, "usesrc");
                                        err_code |= ERR_ALERT | ERR_FATAL;
@@ -4995,11 +4994,11 @@ stats_error_parsing:
                                }
 
                                if (!strcmp(args[cur_arg + 1], "client")) {
-                                       curproxy->options &= ~PR_O_TPXY_MASK;
-                                       curproxy->options |= PR_O_TPXY_CLI;
+                                       curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                       curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
                                } else if (!strcmp(args[cur_arg + 1], "clientip")) {
-                                       curproxy->options &= ~PR_O_TPXY_MASK;
-                                       curproxy->options |= PR_O_TPXY_CIP;
+                                       curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                       curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
                                } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
                                        char *name, *end;
 
@@ -5011,13 +5010,13 @@ stats_error_parsing:
                                        while (*end && !isspace(*end) && *end != ',' && *end != ')')
                                                end++;
 
-                                       curproxy->options &= ~PR_O_TPXY_MASK;
-                                       curproxy->options |= PR_O_TPXY_DYN;
-                                       curproxy->bind_hdr_name = calloc(1, end - name + 1);
-                                       curproxy->bind_hdr_len = end - name;
-                                       memcpy(curproxy->bind_hdr_name, name, end - name);
-                                       curproxy->bind_hdr_name[end-name] = '\0';
-                                       curproxy->bind_hdr_occ = -1;
+                                       curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+                                       curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
+                                       curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
+                                       curproxy->conn_src.bind_hdr_len = end - name;
+                                       memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
+                                       curproxy->conn_src.bind_hdr_name[end-name] = '\0';
+                                       curproxy->conn_src.bind_hdr_occ = -1;
 
                                        /* now look for an occurrence number */
                                        while (isspace(*end))
@@ -5029,10 +5028,10 @@ stats_error_parsing:
                                                        end++;
                                                while (isdigit((int)*end))
                                                        end++;
-                                               curproxy->bind_hdr_occ = strl2ic(name, end-name);
+                                               curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
                                        }
 
-                                       if (curproxy->bind_hdr_occ < -MAX_HDR_HISTORY) {
+                                       if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
                                                Alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
                                                      " occurrences values smaller than %d.\n",
                                                      file, linenum, MAX_HDR_HISTORY);
@@ -5046,8 +5045,8 @@ stats_error_parsing:
                                                err_code |= ERR_ALERT | ERR_FATAL;
                                                goto out;
                                        }
-                                       curproxy->tproxy_addr = *sk;
-                                       curproxy->options |= PR_O_TPXY_ADDR;
+                                       curproxy->conn_src.tproxy_addr = *sk;
+                                       curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
                                }
                                global.last_checks |= LSTCHK_NETADM;
 #if !defined(CONFIG_HAP_LINUX_TPROXY)
@@ -5071,11 +5070,9 @@ stats_error_parsing:
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
-                               if (curproxy->iface_name)
-                                       free(curproxy->iface_name);
-
-                               curproxy->iface_name = strdup(args[cur_arg + 1]);
-                               curproxy->iface_len  = strlen(curproxy->iface_name);
+                               free(curproxy->conn_src.iface_name);
+                               curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
+                               curproxy->conn_src.iface_len  = strlen(curproxy->conn_src.iface_name);
                                global.last_checks |= LSTCHK_NETADM;
 #else
                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
@@ -6717,10 +6714,10 @@ out_uri_auth_compat:
                        }
 
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-                       if (curproxy->bind_hdr_occ) {
-                               curproxy->bind_hdr_occ = 0;
+                       if (curproxy->conn_src.bind_hdr_occ) {
+                               curproxy->conn_src.bind_hdr_occ = 0;
                                Warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
-                                       proxy_type_str(curproxy), curproxy->id, curproxy->bind_hdr_name);
+                                       proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
                                err_code |= ERR_WARN;
                        }
 #endif
@@ -6744,10 +6741,10 @@ out_uri_auth_compat:
                        }
 
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-                       if (curproxy->mode != PR_MODE_HTTP && newsrv->bind_hdr_occ) {
-                               newsrv->bind_hdr_occ = 0;
+                       if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
+                               newsrv->conn_src.bind_hdr_occ = 0;
                                Warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
-                                       proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->bind_hdr_name);
+                                       proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
                                err_code |= ERR_WARN;
                        }
 #endif
index 8c6cf7757a44c2f23256194ff1624c3ee8829668..83d568c1948c18b9378aec9f0c32d4dd524253f7 100644 (file)
@@ -303,17 +303,17 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
         * - server-specific at first
         * - proxy-specific next
         */
-       if (srv != NULL && srv->state & SRV_BIND_SRC) {
+       if (srv != NULL && srv->conn_src.opts & CO_SRC_BIND) {
                int ret, flags = 0;
 
                if (is_addr(&conn->addr.from)) {
-                       switch (srv->state & SRV_TPROXY_MASK) {
-                       case SRV_TPROXY_ADDR:
-                       case SRV_TPROXY_CLI:
+                       switch (srv->conn_src.opts & CO_SRC_TPROXY_MASK) {
+                       case CO_SRC_TPROXY_ADDR:
+                       case CO_SRC_TPROXY_CLI:
                                flags = 3;
                                break;
-                       case SRV_TPROXY_CIP:
-                       case SRV_TPROXY_DYN:
+                       case CO_SRC_TPROXY_CIP:
+                       case CO_SRC_TPROXY_DYN:
                                flags = 1;
                                break;
                        }
@@ -321,16 +321,16 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
 
 #ifdef SO_BINDTODEVICE
                /* Note: this might fail if not CAP_NET_RAW */
-               if (srv->iface_name)
-                       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, srv->iface_name, srv->iface_len + 1);
+               if (srv->conn_src.iface_name)
+                       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, srv->conn_src.iface_name, srv->conn_src.iface_len + 1);
 #endif
 
-               if (srv->sport_range) {
+               if (srv->conn_src.sport_range) {
                        int attempts = 10; /* should be more than enough to find a spare port */
                        struct sockaddr_storage src;
 
                        ret = 1;
-                       src = srv->source_addr;
+                       src = srv->conn_src.source_addr;
 
                        do {
                                /* note: in case of retry, we may have to release a previously
@@ -343,18 +343,18 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
                                        break;
                                attempts--;
 
-                               fdinfo[fd].local_port = port_range_alloc_port(srv->sport_range);
+                               fdinfo[fd].local_port = port_range_alloc_port(srv->conn_src.sport_range);
                                if (!fdinfo[fd].local_port)
                                        break;
 
-                               fdinfo[fd].port_range = srv->sport_range;
+                               fdinfo[fd].port_range = srv->conn_src.sport_range;
                                set_host_port(&src, fdinfo[fd].local_port);
 
                                ret = tcp_bind_socket(fd, flags, &src, &conn->addr.from);
                        } while (ret != 0); /* binding NOK */
                }
                else {
-                       ret = tcp_bind_socket(fd, flags, &srv->source_addr, &conn->addr.from);
+                       ret = tcp_bind_socket(fd, flags, &srv->conn_src.source_addr, &conn->addr.from);
                }
 
                if (ret) {
@@ -378,17 +378,17 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
                        return SN_ERR_RESOURCE;
                }
        }
-       else if (be->options & PR_O_BIND_SRC) {
+       else if (be->conn_src.opts & CO_SRC_BIND) {
                int ret, flags = 0;
 
                if (is_addr(&conn->addr.from)) {
-                       switch (be->options & PR_O_TPXY_MASK) {
-                       case PR_O_TPXY_ADDR:
-                       case PR_O_TPXY_CLI:
+                       switch (be->conn_src.opts & CO_SRC_BIND) {
+                       case CO_SRC_TPROXY_ADDR:
+                       case CO_SRC_TPROXY_CLI:
                                flags = 3;
                                break;
-                       case PR_O_TPXY_CIP:
-                       case PR_O_TPXY_DYN:
+                       case CO_SRC_TPROXY_CIP:
+                       case CO_SRC_TPROXY_DYN:
                                flags = 1;
                                break;
                        }
@@ -396,10 +396,10 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
 
 #ifdef SO_BINDTODEVICE
                /* Note: this might fail if not CAP_NET_RAW */
-               if (be->iface_name)
-                       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, be->iface_name, be->iface_len + 1);
+               if (be->conn_src.iface_name)
+                       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, be->conn_src.iface_name, be->conn_src.iface_len + 1);
 #endif
-               ret = tcp_bind_socket(fd, flags, &be->source_addr, &conn->addr.from);
+               ret = tcp_bind_socket(fd, flags, &be->conn_src.source_addr, &conn->addr.from);
                if (ret) {
                        close(fd);
                        if (ret == 1) {