ASF Bugzilla – Attachment 27455 Details for
Bug 45405
Allow binding port to be set for individual workers for proxy requests
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated patch - against httpd-2.2.20
patch.diff (text/plain), 8.77 KB, created by
D. Stussy
on 2011-09-03 06:18:25 UTC
(
hide
)
Description:
Updated patch - against httpd-2.2.20
Filename:
MIME Type:
Creator:
D. Stussy
Created:
2011-09-03 06:18:25 UTC
Size:
8.77 KB
patch
obsolete
>diff -bur modules/proxy/mod_proxy.c modules/proxy/mod_proxy.c >--- modules/proxy/mod_proxy.c 2010-10-07 18:51:18.000000000 +0000 >+++ modules/proxy/mod_proxy.c 2011-09-03 06:01:37.868574208 +0000 >@@ -33,6 +33,12 @@ > conn_rec *, request_rec *, char *)); > #endif > >+/* Value from /usr/sys/port_kernel.h is it exposed in any portable header? */ >+#define PORT_MAX_PORTS 0x10000 >+ >+/* a sane value for RANGE of bind */ >+#define MIN_RANGE_HINT 8 >+ > #ifndef MAX > #define MAX(x,y) ((x) >= (y) ? (x) : (y)) > #endif >@@ -64,6 +70,8 @@ > (w)->io_buffer_size_set = (c)->io_buffer_size_set; \ > } while (0) > >+static int parse_bind_address(char* val,proxy_bind_addr *bind, apr_pool_t *p); >+ > static const char *set_worker_param(apr_pool_t *p, > proxy_worker *worker, > const char *key, >@@ -290,12 +298,59 @@ > worker->conn_timeout = timeout; > worker->conn_timeout_set = 1; > } >+ else if (!strcasecmp(key, "bind")) { >+ worker->bind = (proxy_bind_addr*) apr_pcalloc(p, sizeof(proxy_bind_addr)); >+ switch (parse_bind_address((char*)val, worker->bind, p)) { >+ case -1: >+ return "ProxySet bind: Invalid address -" >+ " format is <addr>[:<port>+<range>]"; >+ case -2: >+ return "ProxySet bind: Hostname did not resolve."; >+ } >+ } > else { > return "unknown Worker parameter"; > } > return NULL; > } > >+static int parse_bind_address(char* val, proxy_bind_addr* bind, apr_pool_t *p) { >+ char* s_range, *host, *scope_id; >+ s_range = ap_strrchr((char*)val,'+'); >+ if (s_range) { >+ *s_range++ = 0; >+ bind->range = atoi(s_range); >+ if (bind->range < MIN_RANGE_HINT) >+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, >+ "range %u is too low, consider increasing the bind range.", bind->range, NULL); >+ } >+ /* We dont accept a single port with out a range as it would be same >+ * as a single threaded single process http-client >+ * >+ * We do not allow ip:0+0 or ip:0 as it can be specified more clearly >+ * as just ip. >+ * >+ * we dont accept a range without a port either. >+ */ >+ if((apr_parse_addr_port(&host, &scope_id, &bind->port, val, p) != APR_SUCCESS) >+ || scope_id /* we dont know how to use scope_id */ >+ || (!bind->port && s_range) /* only a combo [port+range] is valid */ >+ || (bind->port && (!s_range || bind->range < 0)) /* Let admin specify r=0 if he wants to */ >+ || ((bind->port + bind->range) >= PORT_MAX_PORTS) >+ ) >+ return -1; >+ >+ /* Preparse the address */ >+ if((apr_sockaddr_info_get(&bind->addr, host, APR_UNSPEC, bind->port, 0, p) >+ != APR_SUCCESS) || !bind->addr) >+ return -2; >+ >+ bind->range++; /* update range before passing it back. */ >+ bind->idx = 0; >+ >+ return 0; >+} >+ > static const char *set_balancer_param(proxy_server_conf *conf, > apr_pool_t *p, > proxy_balancer *balancer, >@@ -1111,6 +1166,7 @@ > ps->timeout_set = 0; > ps->badopt = bad_error; > ps->badopt_set = 0; >+ ps->bind = NULL; > ps->pool = p; > > return ps; >@@ -1154,6 +1210,7 @@ > ps->badopt_set = overrides->badopt_set || base->badopt_set; > ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status; > ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set; >+ ps->bind = (overrides->bind ? overrides->bind : base->bind); > ps->pool = p; > return ps; > } >@@ -1751,6 +1808,23 @@ > return NULL; > } > >+static const char* >+ set_proxy_bindaddr(cmd_parms *parms, void *dummy, const char *addr) >+{ >+ proxy_server_conf *psf = >+ ap_get_module_config(parms->server->module_config, &proxy_module); >+ >+ psf->bind = (proxy_bind_addr*) apr_pcalloc(parms->pool, sizeof(proxy_bind_addr)); >+ switch (parse_bind_address((char*)addr, psf->bind, parms->pool)) { >+ case -1: >+ return "ProxyBindAddress: Invalid address -" >+ " format is <addr>[:<port>+<range>]"; >+ case -2: >+ return "ProxyBindAddress: Hostname did not resolve."; >+ } >+ return NULL; >+} >+ > static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) > { > server_rec *s = cmd->server; >@@ -2134,6 +2208,8 @@ > "A balancer or worker name with list of params"), > AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL, > RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"), >+ AP_INIT_TAKE1("ProxyBindAddress", set_proxy_bindaddr, NULL, RSRC_CONF, >+ "Set the source address for a proxied connection."), > {NULL} > }; > >diff -bur modules/proxy/mod_proxy.h modules/proxy/mod_proxy.h >--- modules/proxy/mod_proxy.h 2010-10-07 18:51:18.000000000 +0000 >+++ modules/proxy/mod_proxy.h 2011-09-03 06:03:19.068715552 +0000 >@@ -135,6 +135,14 @@ > typedef struct proxy_conn_pool proxy_conn_pool; > typedef struct proxy_balancer_method proxy_balancer_method; > >+/*bind to local ports*/ >+typedef struct { >+ apr_sockaddr_t *addr; >+ apr_port_t port; >+ apr_port_t range; /* restrict the source ports used by mod_proxy */ >+ int idx; /* pointer to port to try on next call */ >+} proxy_bind_addr; >+ > typedef struct { > apr_array_header_t *proxies; > apr_array_header_t *sec_proxy; >@@ -192,6 +200,10 @@ > status_full > } proxy_status; /* Status display options */ > char proxy_status_set; >+ >+ /*bind to local ports*/ >+ proxy_bind_addr* bind; >+ > apr_pool_t *pool; /* Pool used for allocating this struct */ > } proxy_server_conf; > >@@ -358,6 +370,10 @@ > char disablereuse_set; > apr_interval_time_t conn_timeout; > char conn_timeout_set; >+ >+ /*bind to local ports*/ >+ proxy_bind_addr* bind; >+ > }; > > /* >@@ -794,4 +810,3 @@ > extern int PROXY_DECLARE_DATA proxy_lb_workers; > > #endif /*MOD_PROXY_H*/ >-/** @} */ >diff -bur modules/proxy/proxy_util.c modules/proxy/proxy_util.c >--- modules/proxy/proxy_util.c 2010-08-25 14:10:14.000000000 +0000 >+++ modules/proxy/proxy_util.c 2011-09-03 05:58:54.648343590 +0000 >@@ -2360,6 +2360,31 @@ > } > > >+apr_status_t bind_to_addr(apr_socket_t *newsock, apr_sockaddr_t *laddr, >+ const char *proxy_function, proxy_bind_addr *bind, server_rec *s) >+{ >+ int i; >+ const int idx = bind->idx; >+ const int range = bind->range; >+ const int start = bind->port; >+ for(i = 0; i < range; ++i) { /* loop until we can bind correctly*/ >+ int port = start + ((idx + i) % range); >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: %s: trying to bind to %s:%u", >+ proxy_function, laddr,port, NULL); >+ >+ laddr->sa.sin.sin_port = htons(port); >+ laddr->port = port; >+ if (apr_socket_bind(newsock, laddr) == APR_SUCCESS) { >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: %s: bound to %s:%u", >+ proxy_function, laddr, laddr->port, NULL); >+ bind->idx = (idx + i + 1) % range; /* alternatively (port - start +1 ) */ >+ return APR_SUCCESS; >+ } >+ } >+ return APR_EINVAL; >+} >+ >+ > PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, > proxy_conn_rec *conn, > proxy_worker *worker, >@@ -2445,6 +2470,24 @@ > "proxy: %s: fam %d socket created to connect to %s", > proxy_function, backend_addr->family, worker->hostname); > >+ proxy_bind_addr* bind = (worker->bind ? worker->bind : conf->bind); >+ if (bind) { >+ rv = APR_EINVAL; >+ apr_sockaddr_t *addr; >+ for(addr = bind->addr; addr; addr = addr->next) { >+ if (addr->family != backend_addr->family) continue; >+ rv = bind_to_addr(newsock, addr, proxy_function, bind, s); >+ if (rv == APR_SUCCESS) break; >+ } >+ if (rv != APR_SUCCESS) { >+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "proxy: %s: can not bind to %s:%u+%u", >+ proxy_function,bind->addr, bind->port, bind->range - 1, NULL); >+ return DECLINED; >+ } >+ } else { >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: Not using bind ",proxy_function); >+ } >+ > /* make the connection out of the socket */ > rv = apr_socket_connect(newsock, backend_addr); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45405
:
22264
|
22271
|
22278
|
22283
|
22293
|
22296
|
22300
|
22309
| 27455