[BUILD] backend.c and checks.c did not build without tproxy !

missing #ifdefs.
This commit is contained in:
Willy Tarreau 2008-02-13 22:22:56 +01:00
parent 5c7bf79814
commit 3c3c0122f8
8 changed files with 44 additions and 192 deletions

View File

@ -3844,24 +3844,6 @@ port <port>
inetd for instance. This parameter is ignored if the "check" parameter is not
set. See also the "addr" parameter.
redir <prefix>
The "redir" parameter enables the redirection mode for all GET and HEAD
requests addressing this server. This means that instead of having HAProxy
forward the request to the server, it will send an "HTTP 302" response with
the "Location" header composed of this prefix immediately followed by the
requested URI beginning at the leading '/' of the path component. That means
that no trailing slash should be used after <prefix>. All invalid requests
will be rejected, and all non-GET or HEAD requests will be normally served by
the server. Note that since the response is completely forged, no header
mangling nor cookie insertion is possible in the respose. However, cookies in
requests are still analysed, making this solution completely usable to direct
users to a remote location in case of local disaster. Main use consists in
increasing bandwidth for static servers by having the clients directly
connect to them. Note: never use a relative location here, it would cause a
loop between the client and HAProxy!
Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
rise <count>
The "rise" parameter states that a server will be considered as operational
after <count> consecutive successful health checks. This value defaults to 2

View File

@ -2,7 +2,7 @@
include/types/server.h
This file defines everything related to servers.
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -73,9 +73,7 @@ struct server {
int state; /* server state (SRV_*) */
int prev_state; /* server state before last change (SRV_*) */
int cklen; /* the len of the cookie, to speed up checks */
int rdr_len; /* the length of the redirection prefix */
char *cookie; /* the id set in the cookie */
char *rdr_pfx; /* the redirection prefix */
struct proxy *proxy; /* the proxy this server belongs to */
int cur_sess, cur_sess_max; /* number of currently active sessions (including syn_sent) */

View File

@ -50,7 +50,7 @@
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
#define SN_REDIRECTABLE 0x00000400 /* set if this session is redirectable (GET or HEAD) */
/* unused: 0x00000400 */
/* unused: 0x00000800 */
/* session termination conditions, bits values 0x1000 to 0x7000 (0-7 shift 12) */

View File

@ -1059,13 +1059,6 @@ int assign_server_and_queue(struct session *s)
return SRV_STATUS_INTERNAL;
if (s->flags & SN_ASSIGNED) {
if ((s->flags & SN_REDIRECTABLE) && s->srv && s->srv->rdr_len) {
/* server scheduled for redirection, and already assigned. We
* don't want to go further nor check the queue.
*/
return SRV_STATUS_OK;
}
if (s->srv && s->srv->maxqueue > 0 && s->srv->nbpend >= s->srv->maxqueue) {
s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
s->srv = NULL;
@ -1091,13 +1084,6 @@ int assign_server_and_queue(struct session *s)
err = assign_server(s);
switch (err) {
case SRV_STATUS_OK:
if ((s->flags & SN_REDIRECTABLE) && s->srv && s->srv->rdr_len) {
/* server supporting redirection and it is possible.
* Let's report that and ignore maxconn !
*/
return SRV_STATUS_OK;
}
/* in balance mode, we might have servers with connection limits */
if (s->srv &&
s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
@ -1203,6 +1189,7 @@ int connect_server(struct session *s)
struct sockaddr_in *remote = NULL;
int ret, flags = 0;
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
switch (s->srv->state & SRV_TPROXY_MASK) {
case SRV_TPROXY_ADDR:
remote = (struct sockaddr_in *)&s->srv->tproxy_addr;
@ -1217,6 +1204,7 @@ int connect_server(struct session *s)
remote = (struct sockaddr_in *)&s->cli_addr;
break;
}
#endif
ret = tcpv4_bind_socket(fd, flags, &s->srv->source_addr, remote);
if (ret) {
close(fd);
@ -1240,6 +1228,7 @@ int connect_server(struct session *s)
struct sockaddr_in *remote = NULL;
int ret, flags = 0;
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
switch (s->be->options & PR_O_TPXY_MASK) {
case PR_O_TPXY_ADDR:
remote = (struct sockaddr_in *)&s->be->tproxy_addr;
@ -1254,7 +1243,7 @@ int connect_server(struct session *s)
remote = (struct sockaddr_in *)&s->cli_addr;
break;
}
#endif
ret = tcpv4_bind_socket(fd, flags, &s->be->source_addr, remote);
if (ret) {
close(fd);

View File

@ -1547,11 +1547,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
newsrv->cklen = strlen(args[cur_arg + 1]);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "redir")) {
newsrv->rdr_pfx = strdup(args[cur_arg + 1]);
newsrv->rdr_len = strlen(args[cur_arg + 1]);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "rise")) {
newsrv->rise = atol(args[cur_arg + 1]);
newsrv->health = newsrv->rise;
@ -1696,7 +1691,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
return -1;
}
else {
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
file, linenum, newsrv->id);
return -1;
}
@ -2909,19 +2904,6 @@ int readcfgfile(const char *file)
if (curproxy->options & PR_O_LOGASAP)
curproxy->to_log &= ~LW_BYTES;
/*
* ensure that we're not cross-dressing a TCP server into HTTP.
*/
newsrv = curproxy->srv;
while (newsrv != NULL) {
if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
Alert("parsing %s, %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
file, proxy_type_str(curproxy), curproxy->id, linenum);
goto err;
}
newsrv = newsrv->next;
}
/*
* If this server supports a maxconn parameter, it needs a dedicated
* tasks to fill the emptied slots when a connection leaves.

View File

@ -422,10 +422,12 @@ void process_chk(struct task *t, struct timeval *next)
struct sockaddr_in *remote = NULL;
int ret, flags = 0;
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
if ((s->state & SRV_TPROXY_MASK) == SRV_TPROXY_ADDR) {
remote = (struct sockaddr_in *)&s->tproxy_addr;
flags = 3;
}
#endif
ret = tcpv4_bind_socket(fd, flags, &s->source_addr, remote);
if (ret) {
s->result |= SRV_CHK_ERROR;
@ -445,10 +447,12 @@ void process_chk(struct task *t, struct timeval *next)
struct sockaddr_in *remote = NULL;
int ret, flags = 0;
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
if ((s->proxy->options & PR_O_TPXY_MASK) == PR_O_TPXY_ADDR) {
remote = (struct sockaddr_in *)&s->proxy->tproxy_addr;
flags = 3;
}
#endif
ret = tcpv4_bind_socket(fd, flags, &s->proxy->source_addr, remote);
if (ret) {
s->result |= SRV_CHK_ERROR;

View File

@ -592,54 +592,6 @@ static http_meth_t find_http_meth(const char *str, const int len)
}
/* Parse the URI from the given transaction (which is assumed to be in request
* phase) and look for the "/" beginning the PATH. If not found, return NULL.
* It is returned otherwise.
*/
static char *
http_get_path(struct http_txn *txn)
{
char *ptr, *end;
ptr = txn->req.sol + txn->req.sl.rq.u;
end = ptr + txn->req.sl.rq.u_l;
if (ptr >= end)
return NULL;
/* RFC2616, par. 5.1.2 :
* Request-URI = "*" | absuri | abspath | authority
*/
if (*ptr == '*')
return NULL;
if (isalpha((unsigned char)*ptr)) {
/* this is a scheme as described by RFC3986, par. 3.1 */
ptr++;
while (ptr < end &&
(isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
ptr++;
/* skip '://' */
if (ptr == end || *ptr++ != ':')
return NULL;
if (ptr == end || *ptr++ != '/')
return NULL;
if (ptr == end || *ptr++ != '/')
return NULL;
}
/* skip [user[:passwd]@]host[:[port]] */
while (ptr < end && *ptr != '/')
ptr++;
if (ptr == end)
return NULL;
/* OK, we got the '/' ! */
return ptr;
}
/* Processes the client and server jobs of a session task, then
* puts it back to the wait queue in a clean state, or
* cleans up its resources if it must be deleted. Returns
@ -2499,59 +2451,9 @@ int process_srv(struct session *t)
do {
/* first, get a connection */
if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
t->flags |= SN_REDIRECTABLE;
if (srv_redispatch_connect(t))
return t->srv_state != SV_STIDLE;
if ((t->flags & SN_REDIRECTABLE) && t->srv && t->srv->rdr_len) {
/* Server supporting redirection and it is possible.
* Invalid requests are reported as such. It concerns all
* the largest ones.
*/
struct chunk rdr;
char *path;
int len;
/* 1: create the response header */
rdr.len = strlen(HTTP_302);
rdr.str = trash;
memcpy(rdr.str, HTTP_302, rdr.len);
/* 2: add the server's prefix */
if (rdr.len + t->srv->rdr_len > sizeof(trash))
goto cancel_redir;
memcpy(rdr.str + rdr.len, t->srv->rdr_pfx, t->srv->rdr_len);
rdr.len += t->srv->rdr_len;
/* 3: add the request URI */
path = http_get_path(txn);
if (!path)
goto cancel_redir;
len = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
if (rdr.len + len > sizeof(trash) - 4) /* 4 for CRLF-CRLF */
goto cancel_redir;
memcpy(rdr.str + rdr.len, path, len);
rdr.len += len;
memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
rdr.len += 4;
srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C, 302, &rdr);
/* FIXME: we should increase a counter of redirects per server and per backend. */
if (t->srv)
t->srv->cum_sess++;
return 1;
cancel_redir:
txn->status = 400;
t->fe->failed_req++;
srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C,
400, error_message(t, HTTP_ERR_400));
return 1;
}
/* try to (re-)connect to the server, and fail if we expire the
* number of retries.
*/
@ -5324,9 +5226,39 @@ acl_fetch_path(struct proxy *px, struct session *l4, void *l7, int dir,
/* ensure the indexes are not affected */
return 0;
end = txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
ptr = http_get_path(txn);
if (!ptr)
ptr = txn->req.sol + txn->req.sl.rq.u;
end = ptr + txn->req.sl.rq.u_l;
if (ptr >= end)
return 0;
/* RFC2616, par. 5.1.2 :
* Request-URI = "*" | absuri | abspath | authority
*/
if (*ptr == '*')
return 0;
if (isalpha((unsigned char)*ptr)) {
/* this is a scheme as described by RFC3986, par. 3.1 */
ptr++;
while (ptr < end &&
(isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
ptr++;
/* skip '://' */
if (ptr == end || *ptr++ != ':')
return 0;
if (ptr == end || *ptr++ != '/')
return 0;
if (ptr == end || *ptr++ != '/')
return 0;
}
/* skip [user[:passwd]@]host[:[port]] */
while (ptr < end && *ptr != '/')
ptr++;
if (ptr == end)
return 0;
/* OK, we got the '/' ! */

View File

@ -1,35 +0,0 @@
# This is a test configuration.
# It makes use of a farm built from 4 servers, 3 of which are remote and
# referenced only via an HTTP redirect (302), and the 4th one is normal.
# HTTP requests different from GET/HEAD should reach the servers directly
# while GET/HEAD should get redirected for the 3 first ones.
global
#log /dev/log local0
maxconn 1000
stats socket /tmp/sock1 mode 600
stats timeout 3000
stats maxconn 2000
listen sample1
#log global
#option httplog
mode http
retries 1
option redispatch
contimeout 1000
clitimeout 5000
srvtimeout 5000
maxconn 40000
bind :8080
#balance source
balance roundrobin
option allbackups
server rdr1 127.0.0.1:80 redir http://static1:80 weight 10 check inter 1000 fall 4
server rdr2 127.0.0.2:80 redir http://static2:80 weight 20 check inter 1000 fall 4
server rdr3 127.0.0.3:80 redir http://static3:80 weight 30 check inter 1000 fall 4
server dir4 127.0.0.4:80 redir weight 30 check inter 1000 fall 4
option httpclose
stats uri /stats
stats refresh 5