View | Details | Raw Unified | Return to bug 45405
Collapse All | Expand All

(-)modules/proxy/proxy_util.c (+43 lines)
Lines 2267-2272 Link Here
2267
}
2267
}
2268
#endif /* USE_ALTERNATE_IS_CONNECTED */
2268
#endif /* USE_ALTERNATE_IS_CONNECTED */
2269
2269
2270
apr_status_t bind_to_addr(apr_socket_t *newsock, apr_sockaddr_t *laddr,
2271
        const char *proxy_function, proxy_bind_addr *bind, server_rec *s)
2272
{
2273
    int i;
2274
    const int idx = bind->idx;
2275
    const int range = bind->range;
2276
    const int start = bind->port;
2277
    for(i = 0; i < range; ++i) { /* loop until we can bind correctly*/
2278
        int port = start + ((idx + i) % range);
2279
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: %s: trying to bind to %s:%u",
2280
                proxy_function, laddr,port, NULL);
2281
2282
        laddr->port = port;
2283
        laddr->sa.sin.sin_port = htons(port);
2284
        if (apr_socket_bind(newsock, laddr) == APR_SUCCESS) {
2285
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: %s: bound to %s:%u",
2286
                    proxy_function, laddr, laddr->port, NULL);
2287
            bind->idx = (port - start + 1) % range;
2288
            return APR_SUCCESS;
2289
        }
2290
    }
2291
    return APR_EINVAL;
2292
}
2293
2294
2270
PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
2295
PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
2271
                                            proxy_conn_rec *conn,
2296
                                            proxy_conn_rec *conn,
2272
                                            proxy_worker *worker,
2297
                                            proxy_worker *worker,
Lines 2349-2354 Link Here
2349
                     "proxy: %s: fam %d socket created to connect to %s",
2374
                     "proxy: %s: fam %d socket created to connect to %s",
2350
                     proxy_function, backend_addr->family, worker->hostname);
2375
                     proxy_function, backend_addr->family, worker->hostname);
2351
2376
2377
        proxy_bind_addr* bind = (worker->bind ? worker->bind : conf->bind);
2378
        if (bind) {
2379
            rv = APR_EINVAL;
2380
            apr_sockaddr_t *addr;
2381
            for(addr = bind->addr; addr; addr = addr->next) {
2382
                if (addr->family != backend_addr->family) continue;
2383
                rv = bind_to_addr(newsock, addr, proxy_function, bind, s);
2384
                if (rv == APR_SUCCESS) break;
2385
            }
2386
            if (rv != APR_SUCCESS) {
2387
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "proxy: %s: can not bind to %s:%u+%u",
2388
                        proxy_function,bind->addr, bind->port, bind->range - 1, NULL);
2389
                return DECLINED;
2390
            }
2391
        } else {
2392
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: Not using bind ",proxy_function);
2393
        }
2394
2352
        /* make the connection out of the socket */
2395
        /* make the connection out of the socket */
2353
        rv = apr_socket_connect(newsock, backend_addr);
2396
        rv = apr_socket_connect(newsock, backend_addr);
2354
2397
(-)modules/proxy/mod_proxy.c (+83 lines)
Lines 35-40 Link Here
35
#define MAX(x,y) ((x) >= (y) ? (x) : (y))
35
#define MAX(x,y) ((x) >= (y) ? (x) : (y))
36
#endif
36
#endif
37
37
38
/* Value from /usr/sys/port_kernel.h is it exposed in any portable header? */
39
#define PORT_MAX_PORTS 0x10000
40
41
/* a sane value for RANGE of bind */
42
#define MIN_RANGE_HINT 8
43
38
/* return the sizeof of one lb_worker in scoreboard. */
44
/* return the sizeof of one lb_worker in scoreboard. */
39
static int ap_proxy_lb_worker_size(void)
45
static int ap_proxy_lb_worker_size(void)
40
{
46
{
Lines 70-75 Link Here
70
        (w)->io_buffer_size_set   = (c)->io_buffer_size_set;    \
76
        (w)->io_buffer_size_set   = (c)->io_buffer_size_set;    \
71
    } while (0)
77
    } while (0)
72
78
79
static int parse_bind_address(char* val,
80
                                apr_sockaddr_t **bind_addr,
81
                                apr_port_t *bind_port,
82
                                apr_port_t *range,
83
                                apr_pool_t *p);
84
73
static const char *set_worker_param(apr_pool_t *p,
85
static const char *set_worker_param(apr_pool_t *p,
74
                                    proxy_worker *worker,
86
                                    proxy_worker *worker,
75
                                    const char *key,
87
                                    const char *key,
Lines 281-292 Link Here
281
            return "lbset must be between 0 and 99";
293
            return "lbset must be between 0 and 99";
282
        worker->lbset = ival;
294
        worker->lbset = ival;
283
    }
295
    }
296
    else if (!strcasecmp(key, "bind")) {
297
        proxy_bind_addr* bind =
298
            (proxy_bind_addr*) apr_pcalloc(p, sizeof(proxy_bind_addr));
299
        switch (parse_bind_address((char*)val, &(bind->addr),  &(bind->port), &(bind->range), p)) {
300
            case -1:
301
                return "ProxySet bind:  Invalid address -"
302
                    " format is <addr>[:<port>+<range>]";
303
            case -2:
304
                return "ProxySet bind: Hostname did not resolve.";
305
        }
306
        bind->idx = 0;
307
        worker->bind = bind;
308
    }
284
    else {
309
    else {
285
        return "unknown Worker parameter";
310
        return "unknown Worker parameter";
286
    }
311
    }
287
    return NULL;
312
    return NULL;
288
}
313
}
289
314
315
static int parse_bind_address(char* val,
316
                                apr_sockaddr_t **bind_addr,
317
                                apr_port_t *port,
318
                                apr_port_t *r, apr_pool_t *p) {
319
    char* range, *host, *scope_id;
320
    range = ap_strrchr((char*)val,'+');
321
    if (range) {
322
        *range++ = 0;
323
        *r = atoi(range) + 1;
324
        if (*r < MIN_RANGE_HINT)
325
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
326
                    "range %u is too low, consider increasing the bind range.", (*r) - 1, NULL);
327
    } else *r = 1; /* No range => "+0" -- internally 1 */
328
    /* We dont accept a single port with out a range as it would be same
329
    * as a single threaded single process http-client
330
    *
331
    * We do not allow ip:0+0 or ip:0 as it can be specified more clearly
332
    * as just ip.
333
    *
334
    * we dont accept a range with out a port either.
335
    */
336
    if((apr_parse_addr_port(&host, &scope_id, port, val, p) != APR_SUCCESS)
337
          || scope_id               /* we dont know how to use scope_id */
338
          || (!*port && range)       /* only a combo [port+range] is valid */
339
          || (*port && (!range || *r <= 0)) /* Let admin specify r=0 if he wants to */
340
          || ((*port + *r) > PORT_MAX_PORTS)
341
    )
342
        return -1;
343
    /* Preparse the address */
344
    if((apr_sockaddr_info_get(bind_addr, host, APR_UNSPEC, *port, 0, p)
345
                != APR_SUCCESS) || !*bind_addr)
346
        return -2;
347
}
348
290
static const char *set_balancer_param(proxy_server_conf *conf,
349
static const char *set_balancer_param(proxy_server_conf *conf,
291
                                      apr_pool_t *p,
350
                                      apr_pool_t *p,
292
                                      proxy_balancer *balancer,
351
                                      proxy_balancer *balancer,
Lines 1066-1071 Link Here
1066
    ps->timeout_set = 0;
1125
    ps->timeout_set = 0;
1067
    ps->badopt = bad_error;
1126
    ps->badopt = bad_error;
1068
    ps->badopt_set = 0;
1127
    ps->badopt_set = 0;
1128
    ps->bind = NULL;
1069
    ps->pool = p;
1129
    ps->pool = p;
1070
1130
1071
    return ps;
1131
    return ps;
Lines 1109-1114 Link Here
1109
    ps->badopt_set = overrides->badopt_set || base->badopt_set;
1169
    ps->badopt_set = overrides->badopt_set || base->badopt_set;
1110
    ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status;
1170
    ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status;
1111
    ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set;
1171
    ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set;
1172
    ps->bind = (overrides->bind ? overrides->bind : base->bind);
1112
    ps->pool = p;
1173
    ps->pool = p;
1113
    return ps;
1174
    return ps;
1114
}
1175
}
Lines 1706-1711 Link Here
1706
    return NULL;
1767
    return NULL;
1707
}
1768
}
1708
1769
1770
static const char*
1771
    set_proxy_bindaddr(cmd_parms *parms, void *dummy, const char *addr)
1772
{
1773
    proxy_server_conf *psf =
1774
        ap_get_module_config(parms->server->module_config, &proxy_module);
1775
    
1776
    proxy_bind_addr* bind =
1777
        (proxy_bind_addr*) apr_pcalloc(parms->pool, sizeof(proxy_bind_addr));
1778
    switch (parse_bind_address((char*)addr, &(bind->addr),  &(bind->port), &(bind->range), parms->pool)) {
1779
        case -1:
1780
            return "ProxyBindAddress:  Invalid address -"
1781
                " format is <addr>[:<port>+<range>]";
1782
        case -2:
1783
            return "ProxyBindAddress: Hostname did not resolve.";
1784
    }
1785
    bind->idx = 0;
1786
    psf->bind = bind;
1787
    return NULL;
1788
}
1789
1709
static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
1790
static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
1710
{
1791
{
1711
    server_rec *s = cmd->server;
1792
    server_rec *s = cmd->server;
Lines 2088-2093 Link Here
2088
     "A balancer or worker name with list of params"),
2169
     "A balancer or worker name with list of params"),
2089
    AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL,
2170
    AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL,
2090
     RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"),
2171
     RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"),
2172
    AP_INIT_TAKE1("ProxyBindAddress", set_proxy_bindaddr, NULL, RSRC_CONF,
2173
            "Set the source address for a proxied connection."),
2091
    {NULL}
2174
    {NULL}
2092
};
2175
};
2093
2176
(-)modules/proxy/mod_proxy.h (+16 lines)
Lines 133-139 Link Here
133
typedef struct proxy_conn_pool proxy_conn_pool;
133
typedef struct proxy_conn_pool proxy_conn_pool;
134
typedef struct proxy_balancer_method proxy_balancer_method;
134
typedef struct proxy_balancer_method proxy_balancer_method;
135
135
136
/*bind to local ports*/
136
typedef struct {
137
typedef struct {
138
    apr_sockaddr_t *addr;
139
    apr_port_t port;
140
    apr_port_t range;             /* restrict the source ports used by mod_proxy */
141
    int idx;
142
} proxy_bind_addr;
143
144
typedef struct {
137
    apr_array_header_t *proxies;
145
    apr_array_header_t *proxies;
138
    apr_array_header_t *sec_proxy;
146
    apr_array_header_t *sec_proxy;
139
    apr_array_header_t *aliases;
147
    apr_array_header_t *aliases;
Lines 190-195 Link Here
190
        status_full
198
        status_full
191
    } proxy_status;             /* Status display options */
199
    } proxy_status;             /* Status display options */
192
    char proxy_status_set;
200
    char proxy_status_set;
201
202
    /*bind to local ports*/
203
    proxy_bind_addr* bind;
204
193
    apr_pool_t *pool;           /* Pool used for allocating this struct */
205
    apr_pool_t *pool;           /* Pool used for allocating this struct */
194
} proxy_server_conf;
206
} proxy_server_conf;
195
207
Lines 352-357 Link Here
352
    char            retry_set;
364
    char            retry_set;
353
    char            disablereuse;
365
    char            disablereuse;
354
    char            disablereuse_set;
366
    char            disablereuse_set;
367
368
    /*bind to local ports*/
369
    proxy_bind_addr* bind;
370
355
};
371
};
356
372
357
/*
373
/*

Return to bug 45405