blob: 435a1e206b036d90dbd8ef384795258ec109b550 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Proxy variables and functions.
3 *
Willy Tarreaud825eef2007-05-12 22:35:00 +02004 * Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <fcntl.h>
14#include <unistd.h>
15#include <sys/types.h>
16#include <sys/socket.h>
17#include <sys/stat.h>
18
Willy Tarreau2dd0d472006-06-29 17:53:05 +020019#include <common/defaults.h>
20#include <common/compat.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020021#include <common/config.h>
Willy Tarreaud740bab2007-10-28 11:14:07 +010022#include <common/errors.h>
Willy Tarreau4d2d0982007-05-14 00:39:29 +020023#include <common/memory.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020024#include <common/time.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020025
26#include <types/global.h>
27#include <types/polling.h>
28
29#include <proto/client.h>
Alexandre Cassen87ea5482007-10-11 20:48:58 +020030#include <proto/backend.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020031#include <proto/fd.h>
32#include <proto/log.h>
33#include <proto/proxy.h>
34
35
36int listeners; /* # of listeners */
37struct proxy *proxy = NULL; /* list of all existing proxies */
38
Willy Tarreau977b8e42006-12-29 14:19:17 +010039/*
40 * This function returns a string containing the type of the proxy in a format
41 * suitable for error messages, from its capabilities.
42 */
Willy Tarreau2b5652f2006-12-31 17:46:05 +010043const char *proxy_type_str(struct proxy *proxy)
Willy Tarreau977b8e42006-12-29 14:19:17 +010044{
Willy Tarreau2b5652f2006-12-31 17:46:05 +010045 int cap = proxy->cap;
Willy Tarreau977b8e42006-12-29 14:19:17 +010046 if ((cap & PR_CAP_LISTEN) == PR_CAP_LISTEN)
47 return "listener";
48 else if (cap & PR_CAP_FE)
49 return "frontend";
50 else if (cap & PR_CAP_BE)
51 return "backend";
52 else if (cap & PR_CAP_RS)
53 return "ruleset";
54 else
55 return "proxy";
56}
57
Willy Tarreaubaaee002006-06-26 02:48:02 +020058
59/*
Willy Tarreau2ff76222007-04-09 19:29:56 +020060 * This function creates all proxy sockets. It should be done very early,
61 * typically before privileges are dropped. The sockets will be registered
62 * but not added to any fd_set, in order not to loose them across the fork().
63 * The proxies also start in IDLE state, meaning that it will be
64 * maintain_proxies that will finally complete their loading.
65 *
66 * Its return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
67 * Retryable errors will only be printed if <verbose> is not zero.
Willy Tarreaubaaee002006-06-26 02:48:02 +020068 */
69int start_proxies(int verbose)
70{
71 struct proxy *curproxy;
72 struct listener *listener;
73 int err = ERR_NONE;
74 int fd, pxerr;
75
76 for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
77 if (curproxy->state != PR_STNEW)
78 continue; /* already initialized */
79
80 pxerr = 0;
81 for (listener = curproxy->listen; listener != NULL; listener = listener->next) {
82 if (listener->fd != -1)
83 continue; /* already initialized */
84
85 if ((fd = socket(listener->addr.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
86 if (verbose)
87 Alert("cannot create listening socket for proxy %s. Aborting.\n",
88 curproxy->id);
89 err |= ERR_RETRYABLE;
90 pxerr |= 1;
91 continue;
92 }
93
94 if (fd >= global.maxsock) {
95 Alert("socket(): not enough free sockets for proxy %s. Raise -n argument. Aborting.\n",
96 curproxy->id);
97 close(fd);
98 err |= ERR_FATAL;
99 pxerr |= 1;
100 break;
101 }
102
103 if ((fcntl(fd, F_SETFL, O_NONBLOCK) == -1) ||
104 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
105 (char *) &one, sizeof(one)) == -1)) {
106 Alert("cannot make socket non-blocking for proxy %s. Aborting.\n",
107 curproxy->id);
108 close(fd);
109 err |= ERR_FATAL;
110 pxerr |= 1;
111 break;
112 }
113
114 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) {
115 Alert("cannot do so_reuseaddr for proxy %s. Continuing.\n",
116 curproxy->id);
117 }
Alexandre Cassen87ea5482007-10-11 20:48:58 +0200118
119 if (curproxy->options & PR_O_TCP_NOLING)
120 setsockopt(fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200121
122#ifdef SO_REUSEPORT
123 /* OpenBSD supports this. As it's present in old libc versions of Linux,
124 * it might return an error that we will silently ignore.
125 */
126 setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &one, sizeof(one));
127#endif
128 if (bind(fd,
129 (struct sockaddr *)&listener->addr,
130 listener->addr.ss_family == AF_INET6 ?
131 sizeof(struct sockaddr_in6) :
132 sizeof(struct sockaddr_in)) == -1) {
133 if (verbose)
134 Alert("cannot bind socket for proxy %s. Aborting.\n",
135 curproxy->id);
136 close(fd);
137 err |= ERR_RETRYABLE;
138 pxerr |= 1;
139 continue;
140 }
141
142 if (listen(fd, curproxy->maxconn) == -1) {
143 if (verbose)
144 Alert("cannot listen to socket for proxy %s. Aborting.\n",
145 curproxy->id);
146 close(fd);
147 err |= ERR_RETRYABLE;
148 pxerr |= 1;
149 continue;
150 }
151
152 /* the socket is ready */
153 listener->fd = fd;
154
155 /* the function for the accept() event */
Willy Tarreau7a966482007-04-15 10:58:02 +0200156 fd_insert(fd);
Willy Tarreau54469402006-07-29 16:59:06 +0200157 fdtab[fd].cb[DIR_RD].f = &event_accept;
158 fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
159 fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200160 fdtab[fd].owner = (struct task *)curproxy; /* reference the proxy instead of a task */
161 fdtab[fd].state = FD_STLISTEN;
Willy Tarreaue94ebd02007-10-09 17:14:37 +0200162 fdtab[fd].peeraddr = NULL;
163 fdtab[fd].peerlen = 0;
Willy Tarreau3d32d3a2007-04-15 11:31:05 +0200164 fdtab[fd].ev = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200165 listeners++;
166 }
167
168 if (!pxerr) {
Willy Tarreau2ff76222007-04-09 19:29:56 +0200169 curproxy->state = PR_STIDLE;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200170 send_log(curproxy, LOG_NOTICE, "Proxy %s started.\n", curproxy->id);
171 }
172 }
173
174 return err;
175}
176
177
178/*
179 * this function enables proxies when there are enough free sessions,
180 * or stops them when the table is full. It is designed to be called from the
Willy Tarreaud825eef2007-05-12 22:35:00 +0200181 * select_loop(). It returns the date of next expiration event during stop
182 * time, ETERNITY otherwise.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200183 */
Willy Tarreaud825eef2007-05-12 22:35:00 +0200184void maintain_proxies(struct timeval *next)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200185{
186 struct proxy *p;
187 struct listener *l;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200188
189 p = proxy;
Willy Tarreaud825eef2007-05-12 22:35:00 +0200190 tv_eternity(next);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200191
192 /* if there are enough free sessions, we'll activate proxies */
193 if (actconn < global.maxconn) {
194 while (p) {
Willy Tarreauf1221aa2006-12-17 22:14:12 +0100195 if (p->feconn < p->maxconn) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200196 if (p->state == PR_STIDLE) {
197 for (l = p->listen; l != NULL; l = l->next) {
Willy Tarreauf161a342007-04-08 16:59:42 +0200198 EV_FD_SET(l->fd, DIR_RD);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200199 }
200 p->state = PR_STRUN;
201 }
202 }
203 else {
204 if (p->state == PR_STRUN) {
205 for (l = p->listen; l != NULL; l = l->next) {
Willy Tarreauf161a342007-04-08 16:59:42 +0200206 EV_FD_CLR(l->fd, DIR_RD);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200207 }
208 p->state = PR_STIDLE;
209 }
210 }
211 p = p->next;
212 }
213 }
214 else { /* block all proxies */
215 while (p) {
216 if (p->state == PR_STRUN) {
217 for (l = p->listen; l != NULL; l = l->next) {
Willy Tarreauf161a342007-04-08 16:59:42 +0200218 EV_FD_CLR(l->fd, DIR_RD);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200219 }
220 p->state = PR_STIDLE;
221 }
222 p = p->next;
223 }
224 }
225
226 if (stopping) {
227 p = proxy;
228 while (p) {
229 if (p->state != PR_STSTOPPED) {
230 int t;
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200231 t = tv_ms_remain2(&now, &p->stop_time);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200232 if (t == 0) {
233 Warning("Proxy %s stopped.\n", p->id);
234 send_log(p, LOG_WARNING, "Proxy %s stopped.\n", p->id);
235
236 for (l = p->listen; l != NULL; l = l->next) {
237 fd_delete(l->fd);
238 listeners--;
239 }
240 p->state = PR_STSTOPPED;
Willy Tarreau4d2d0982007-05-14 00:39:29 +0200241 /* try to free more memory */
242 pool_gc2();
Willy Tarreaubaaee002006-06-26 02:48:02 +0200243 }
244 else {
Willy Tarreaud825eef2007-05-12 22:35:00 +0200245 tv_bound(next, &p->stop_time);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200246 }
247 }
248 p = p->next;
249 }
250 }
Willy Tarreaud825eef2007-05-12 22:35:00 +0200251 return;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200252}
253
254
255/*
256 * this function disables health-check servers so that the process will quickly be ignored
257 * by load balancers. Note that if a proxy was already in the PAUSED state, then its grace
258 * time will not be used since it would already not listen anymore to the socket.
259 */
260void soft_stop(void)
261{
262 struct proxy *p;
263
264 stopping = 1;
265 p = proxy;
266 tv_now(&now); /* else, the old time before select will be used */
267 while (p) {
268 if (p->state != PR_STSTOPPED) {
269 Warning("Stopping proxy %s in %d ms.\n", p->id, p->grace);
270 send_log(p, LOG_WARNING, "Stopping proxy %s in %d ms.\n", p->id, p->grace);
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200271 tv_ms_add(&p->stop_time, &now, p->grace);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200272 }
273 p = p->next;
274 }
275}
276
277
278/*
279 * Linux unbinds the listen socket after a SHUT_RD, and ignores SHUT_WR.
280 * Solaris refuses either shutdown().
281 * OpenBSD ignores SHUT_RD but closes upon SHUT_WR and refuses to rebind.
282 * So a common validation path involves SHUT_WR && listen && SHUT_RD.
283 * If disabling at least one listener returns an error, then the proxy
284 * state is set to PR_STERROR because we don't know how to resume from this.
285 */
286void pause_proxy(struct proxy *p)
287{
288 struct listener *l;
289 for (l = p->listen; l != NULL; l = l->next) {
290 if (shutdown(l->fd, SHUT_WR) == 0 &&
291 listen(l->fd, p->maxconn) == 0 &&
292 shutdown(l->fd, SHUT_RD) == 0) {
Willy Tarreauf161a342007-04-08 16:59:42 +0200293 EV_FD_CLR(l->fd, DIR_RD);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200294 if (p->state != PR_STERROR)
295 p->state = PR_STPAUSED;
296 }
297 else
298 p->state = PR_STERROR;
299 }
300}
301
302/*
303 * This function temporarily disables listening so that another new instance
304 * can start listening. It is designed to be called upon reception of a
305 * SIGTTOU, after which either a SIGUSR1 can be sent to completely stop
306 * the proxy, or a SIGTTIN can be sent to listen again.
307 */
308void pause_proxies(void)
309{
310 int err;
311 struct proxy *p;
312
313 err = 0;
314 p = proxy;
315 tv_now(&now); /* else, the old time before select will be used */
316 while (p) {
317 if (p->state != PR_STERROR &&
318 p->state != PR_STSTOPPED &&
319 p->state != PR_STPAUSED) {
320 Warning("Pausing proxy %s.\n", p->id);
321 send_log(p, LOG_WARNING, "Pausing proxy %s.\n", p->id);
322 pause_proxy(p);
323 if (p->state != PR_STPAUSED) {
324 err |= 1;
325 Warning("Proxy %s failed to enter pause mode.\n", p->id);
326 send_log(p, LOG_WARNING, "Proxy %s failed to enter pause mode.\n", p->id);
327 }
328 }
329 p = p->next;
330 }
331 if (err) {
332 Warning("Some proxies refused to pause, performing soft stop now.\n");
333 send_log(p, LOG_WARNING, "Some proxies refused to pause, performing soft stop now.\n");
334 soft_stop();
335 }
336}
337
338
339/*
340 * This function reactivates listening. This can be used after a call to
341 * sig_pause(), for example when a new instance has failed starting up.
342 * It is designed to be called upon reception of a SIGTTIN.
343 */
344void listen_proxies(void)
345{
346 struct proxy *p;
347 struct listener *l;
348
349 p = proxy;
350 tv_now(&now); /* else, the old time before select will be used */
351 while (p) {
352 if (p->state == PR_STPAUSED) {
353 Warning("Enabling proxy %s.\n", p->id);
354 send_log(p, LOG_WARNING, "Enabling proxy %s.\n", p->id);
355
356 for (l = p->listen; l != NULL; l = l->next) {
357 if (listen(l->fd, p->maxconn) == 0) {
Willy Tarreauf1221aa2006-12-17 22:14:12 +0100358 if (actconn < global.maxconn && p->feconn < p->maxconn) {
Willy Tarreauf161a342007-04-08 16:59:42 +0200359 EV_FD_SET(l->fd, DIR_RD);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200360 p->state = PR_STRUN;
361 }
362 else
363 p->state = PR_STIDLE;
364 } else {
365 int port;
366
367 if (l->addr.ss_family == AF_INET6)
368 port = ntohs(((struct sockaddr_in6 *)(&l->addr))->sin6_port);
369 else
370 port = ntohs(((struct sockaddr_in *)(&l->addr))->sin_port);
371
372 Warning("Port %d busy while trying to enable proxy %s.\n",
373 port, p->id);
374 send_log(p, LOG_WARNING, "Port %d busy while trying to enable proxy %s.\n",
375 port, p->id);
376 /* Another port might have been enabled. Let's stop everything. */
377 pause_proxy(p);
378 break;
379 }
380 }
381 }
382 p = p->next;
383 }
384}
385
386
387/*
388 * Local variables:
389 * c-indent-level: 8
390 * c-basic-offset: 8
391 * End:
392 */