diff --git a/CHANGELOG b/CHANGELOG index b8ae2ac712..2a65fa4231 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ ChangeLog : =========== +2004/04/18 : 1.2.1 (1.1.28) + - send an EMERG log when no server is available for a given proxy + - added the '-c' command line option to syntactically check the + configuration file without starting the service. + 2003/11/09 : 1.2.0 - the same as 1.1.27 + IPv6 support on the client side diff --git a/TODO b/TODO index c11c82f3d6..d54fbd139a 100644 --- a/TODO +++ b/TODO @@ -80,17 +80,25 @@ ok> 5) implémenter "balance source" pour faire un hash sur la source. permettre de spécifier un masque sur lequel s'applique le hachage, ainsi qu'une option pour hacher en fonction de l'adresse dans le - champ "x-forwarded-for". + champ "x-forwarded-for". Problème pour le support des pannes: ce + type de hash est utile là où la persistence par cookie ne peut pas + s'appliquer, donc comment faire pour assurer un maximum de persistence + en cas de panne ? 6) possibilité d'un process séparé par listen : listen XXX fork [ group_id ] -le fait de spécifier group_id fera que toutes les instances utilisant le même -identifiant de groupe seront gérées par un même processus. + le fait de spécifier group_id fera que toutes les instances utilisant le + même identifiant de groupe seront gérées par un même processus. -> plus souple et plus compréhensible de faire des sections par processus, - ce qui résoud également le cas ci-dessous + ce qui résoud également le cas ci-dessous. Ex: + process_group X + nbproc X + uid X + chroot X + listen ... 7) gérer un chroot/uid/gid différents par process : listen XXX @@ -111,3 +119,23 @@ ok> de forcer la m ok> ex: option httpchk -> OPTIONS / HTTP/1.0 ok> option httpchk /test -> OPTIONS /test HTTP/1.0 ok> option httpchk HEAD / HTTP/1.0\nHost:\ www -> tel quel + +Todo for 1.1 +============ +* "no more server" alert +* config check +- anti-flapping + +Todo for 1.2 +============ +- direct +- new config syntax allowing braces to be able to shorten lines +- insert/learn/check/log unique request ID, and add the ability + to block bad responses. +- IPv6 : +* listen [ip4.ip4.ip4.ip4]:port[-port] +* listen [ip6::...ip6]/port[-port] +- server xxx ipv4 | ipv4: | ipv4:port[-port] | ipv6/ | ipv6/port[-port] + +- weighted round robin + diff --git a/haproxy.c b/haproxy.c index 10bb3e031a..91d597e3e1 100644 --- a/haproxy.c +++ b/haproxy.c @@ -1,6 +1,6 @@ /* * HA-Proxy : High Availability-enabled HTTP/TCP proxy - * 2000-2003 - Willy Tarreau - willy AT meta-x DOT org. + * 2000-2004 - Willy Tarreau - willy AT meta-x DOT org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -53,8 +53,8 @@ #include #endif -#define HAPROXY_VERSION "1.1.27-ipv6" -#define HAPROXY_DATE "2003/11/09" +#define HAPROXY_VERSION "1.2.1" +#define HAPROXY_DATE "2004/04/18" /* this is for libc5 for example */ #ifndef TCP_NODELAY @@ -293,6 +293,7 @@ int strlcpy2(char *dst, const char *src, int size) { #define MODE_LOG 4 #define MODE_DAEMON 8 #define MODE_QUIET 16 +#define MODE_CHECK 32 /* server flags */ #define SRV_RUNNING 1 /* the server is UP */ @@ -537,6 +538,9 @@ static regmatch_t pmatch[MAX_MATCH]; /* rm_so, rm_eo for regular expressions */ /* this is used to drain data, and as a temporary buffer for sprintf()... */ static char trash[BUFSIZE]; +const int zero = 0; +const int one = 1; + /* * Syslog facilities and levels. Conforming to RFC3164. */ @@ -665,7 +669,7 @@ int process_session(struct task *t); void display_version() { printf("HA-Proxy version " HAPROXY_VERSION " " HAPROXY_DATE"\n"); - printf("Copyright 2000-2003 Willy Tarreau \n\n"); + printf("Copyright 2000-2004 Willy Tarreau \n\n"); } /* @@ -687,6 +691,7 @@ void usage(char *name) { #endif " -D goes daemon ; implies -q\n" " -q quiet mode : don't display messages\n" + " -c check mode : only check config file and exit\n" " -n sets the maximum total # of connections (%d)\n" " -N sets the default, per-proxy maximum # of connections (%d)\n" " -p writes pids of all children to this file\n\n", @@ -1446,7 +1451,6 @@ static inline struct server *find_server(struct proxy *px) { * it's OK, -1 if it's impossible. */ int connect_server(struct session *s) { - int one = 1; int fd; // fprintf(stderr,"connect_server : s=%p\n",s); @@ -2033,7 +2037,6 @@ int event_accept(int fd) { struct session *s; struct task *t; int cfd; - int one = 1; while (p->nbconn < p->maxconn) { struct sockaddr_storage addr; @@ -3833,7 +3836,6 @@ int process_chk(struct task *t) { struct server *s = t->context; struct sockaddr_in sa; int fd = s->curfd; - int one = 1; //fprintf(stderr, "process_chk: task=%p\n", t); @@ -3899,15 +3901,17 @@ int process_chk(struct task *t) { if (s->health > s->rise) s->health--; /* still good */ else { - if (s->health == s->rise) { - if (!(global.mode & MODE_QUIET)) - Warning("server %s/%s DOWN.\n", s->proxy->id, s->id); - - send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id); - } - - s->health = 0; /* failure */ s->state &= ~SRV_RUNNING; + if (s->health == s->rise) { + Warning("Server %s/%s DOWN.\n", s->proxy->id, s->id); + send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id); + + if (find_server(s->proxy) == NULL) { + Alert("Proxy %s has no server available !\n", s->proxy->id); + send_log(s->proxy, LOG_EMERG, "Proxy %s has no server available !\n", s->proxy->id); + } + } + s->health = 0; /* failure */ } //fprintf(stderr, "process_chk: 7\n"); @@ -3922,8 +3926,7 @@ int process_chk(struct task *t) { s->health++; /* was bad, stays for a while */ if (s->health >= s->rise) { if (s->health == s->rise) { - if (!(global.mode & MODE_QUIET)) - Warning("server %s/%s UP.\n", s->proxy->id, s->id); + Warning("server %s/%s UP.\n", s->proxy->id, s->id); send_log(s->proxy, LOG_NOTICE, "Server %s/%s is UP.\n", s->proxy->id, s->id); } @@ -3941,15 +3944,19 @@ int process_chk(struct task *t) { if (s->health > s->rise) s->health--; /* still good */ else { - if (s->health == s->rise) { - if (!(global.mode & MODE_QUIET)) - Warning("server %s/%s DOWN.\n", s->proxy->id, s->id); + s->state &= ~SRV_RUNNING; + if (s->health == s->rise) { + Warning("Server %s/%s DOWN.\n", s->proxy->id, s->id); send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id); + + if (find_server(s->proxy) == NULL) { + Alert("Proxy %s has no server available !\n", s->proxy->id); + send_log(s->proxy, LOG_EMERG, "Proxy %s has no server available !\n", s->proxy->id); + } } s->health = 0; /* failure */ - s->state &= ~SRV_RUNNING; } s->curfd = -1; //FD_CLR(fd, StaticWriteEvent); @@ -4280,6 +4287,12 @@ void sig_dump_state(int sig) { } s = s->next; } + + if (find_server(p) == NULL) { + Warning("SIGHUP: proxy %s has no server available !\n", p); + send_log(p, LOG_NOTICE, "SIGHUP: proxy %s has no server available !\n", p); + } + p = p->next; } signal(sig, sig_dump_state); @@ -5691,7 +5704,7 @@ void init(int argc, char **argv) { int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */ if (1< 0) global.maxconn = cfg_maxconn; @@ -5814,7 +5836,6 @@ void init(int argc, char **argv) { int start_proxies() { struct proxy *curproxy; struct listener *listener; - int one = 1; int fd; for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {