#define MODE_QUIET 16
#define MODE_CHECK 32
#define MODE_VERBOSE 64
+#define MODE_STARTING 128
/* server flags */
#define SRV_RUNNING 1 /* the server is UP */
/*
- * Displays the message on stderr with the date and pid.
+ * Displays the message on stderr with the date and pid. Overrides the quiet
+ * mode during startup.
*/
void Alert(char *fmt, ...) {
va_list argp;
struct timeval tv;
struct tm *tm;
- if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
+ if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
va_start(argp, fmt);
gettimeofday(&tv, NULL);
/* 2) look for the addr/port delimiter, it's the last colon. */
if ((range = strrchr(str, ':')) == NULL) {
Alert("Missing port number: '%s'\n", str);
+ goto fail;
}
*range++ = 0;
if (!inet_pton(ss.ss_family, str, &((struct sockaddr_in6 *)&ss)->sin6_addr)) {
Alert("Invalid server address: '%s'\n", str);
+ goto fail;
}
}
else {
if ((he = gethostbyname(str)) == NULL) {
Alert("Invalid server name: '%s'\n", str);
+ goto fail;
}
else
((struct sockaddr_in *)&ss)->sin_addr =
end = atol(range);
}
- for (port = atol(range); port <= end; port++) {
+ port = atol(range);
+
+ if (port < 1 || port > 65535) {
+ Alert("Invalid port '%d' specified for address '%s'.\n", port, str);
+ goto fail;
+ }
+
+ if (end < 1 || end > 65535) {
+ Alert("Invalid port '%d' specified for address '%s'.\n", end, str);
+ goto fail;
+ }
+
+ for (; port <= end; port++) {
l = (struct listener *)calloc(1, sizeof(struct listener));
l->next = tail;
tail = l;
} /* end while(next) */
free(dupstr);
return tail;
+ fail:
+ free(dupstr);
+ return NULL;
}
curproxy->next = proxy;
proxy = curproxy;
curproxy->id = strdup(args[1]);
- if (strchr(args[2], ':') != NULL)
+
+ /* parse the listener address if any */
+ if (*args[2]) {
curproxy->listen = str2listener(args[2], curproxy->listen);
+ if (!curproxy->listen)
+ return -1;
+ }
/* set default values */
curproxy->state = defproxy.state;
return -1;
}
curproxy->listen = str2listener(args[1], curproxy->listen);
+ if (!curproxy->listen)
+ return -1;
return 0;
}
else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
curproxy = curproxy->next;
continue;
}
- if ((curproxy->mode != PR_MODE_HEALTH) &&
+
+ if (curproxy->listen == NULL) {
+ Alert("parsing %s : listener %s has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n", file, curproxy->id);
+ cfgerr++;
+ }
+ else if ((curproxy->mode != PR_MODE_HEALTH) &&
!(curproxy->options & (PR_O_TRANSP | PR_O_BALANCE)) &&
(*(int *)&curproxy->dispatch_addr.sin_addr == 0)) {
Alert("parsing %s : listener %s has no dispatch address and is not in transparent or balance mode.\n",
argv++; argc--;
}
- global.mode = (arg_mode & (MODE_DAEMON | MODE_VERBOSE | MODE_QUIET | MODE_CHECK | MODE_DEBUG));
+ global.mode = MODE_STARTING | /* during startup, we want most of the alerts */
+ (arg_mode & (MODE_DAEMON | MODE_VERBOSE | MODE_QUIET | MODE_CHECK | MODE_DEBUG));
if (!cfg_cfgfile)
usage(old_argv);
FILE *pidfile = NULL;
init(argc, argv);
- if (global.mode & MODE_QUIET) {
- /* detach from the tty */
- fclose(stdin); fclose(stdout); fclose(stderr);
- close(0); close(1); close(2);
- }
-
signal(SIGQUIT, dump);
signal(SIGUSR1, sig_soft_stop);
signal(SIGHUP, sig_dump_state);
signal(SIGPIPE, SIG_IGN);
#endif
+ /* start_proxies() sends an alert when it fails. */
if (start_proxies() < 0)
exit(1);
+ if (listeners == 0) {
+ Alert("[%s.main()] No enabled listener found (check the <listen> keywords) ! Exiting.\n", argv[0]);
+ exit(1);
+ }
+
+ /* MODE_QUIET can inhibit alerts and warnings below this line */
+
+ global.mode &= ~MODE_STARTING;
+ if (global.mode & MODE_QUIET) {
+ /* detach from the tty */
+ fclose(stdin); fclose(stdout); fclose(stderr);
+ close(0); close(1); close(2);
+ }
+
/* open log & pid files before the chroot */
if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
int pidfd;