From ef9a36055511b14c0a072e5f817143eecade5cfd Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 8 Dec 2012 22:29:20 +0100 Subject: [PATCH] MEDIUM: connection: introduce "struct conn_src" for servers and proxies 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 | 32 ++++++++++ include/types/proxy.h | 20 +----- include/types/server.h | 20 +----- src/backend.c | 40 ++++++------ src/cfgparse.c | 125 ++++++++++++++++++------------------- src/proto_tcp.c | 44 ++++++------- 6 files changed, 141 insertions(+), 140 deletions(-) diff --git a/include/types/connection.h b/include/types/connection.h index b2396c44d2..255811ca64 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -29,6 +29,7 @@ #include #include +#include #include /* 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 diff --git a/include/types/proxy.h b/include/types/proxy.h index 5d99423abc..ceb14d1fdc 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -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 */ diff --git a/include/types/server.h b/include/types/server.h index ac7ab7bacd..b58a06207b 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -48,16 +47,12 @@ #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 */ diff --git a/src/backend.c b/src/backend.c index 96545a9918..f81b75f8d6 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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)); } diff --git a/src/cfgparse.c b/src/cfgparse.c index f1cb96ef93..4e5963e42f 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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 diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 8c6cf7757a..83d568c194 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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) { -- 2.39.5