blob: f7dd67571501acbaab433a3f4f41ded6f97b5506 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Backend variables and functions.
3 *
4 * Copyright 2000-2006 Willy Tarreau <w@1wt.eu>
5 *
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 <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <syslog.h>
Willy Tarreauf19cf372006-11-14 15:40:51 +010018#include <string.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020019
Willy Tarreau2dd0d472006-06-29 17:53:05 +020020#include <common/compat.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020021#include <common/config.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020022#include <common/time.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020023
24#include <types/buffers.h>
25#include <types/global.h>
26#include <types/polling.h>
27#include <types/proxy.h>
28#include <types/server.h>
29#include <types/session.h>
30
31#include <proto/backend.h>
32#include <proto/fd.h>
Willy Tarreau80587432006-12-24 17:47:20 +010033#include <proto/httperr.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <proto/log.h>
35#include <proto/proto_http.h>
36#include <proto/queue.h>
37#include <proto/stream_sock.h>
38#include <proto/task.h>
39
Willy Tarreau77074d52006-11-12 23:57:19 +010040#ifdef CONFIG_HAP_CTTPROXY
41#include <import/ip_tproxy.h>
42#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +020043
44/*
45 * This function recounts the number of usable active and backup servers for
46 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
47 * This function also recomputes the total active and backup weights.
48 */
49void recount_servers(struct proxy *px)
50{
51 struct server *srv;
52
53 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
54 for (srv = px->srv; srv != NULL; srv = srv->next) {
55 if (srv->state & SRV_RUNNING) {
56 if (srv->state & SRV_BACKUP) {
57 px->srv_bck++;
58 px->tot_wbck += srv->eweight + 1;
59 } else {
60 px->srv_act++;
61 px->tot_wact += srv->eweight + 1;
62 }
63 }
64 }
65}
66
67/* This function recomputes the server map for proxy px. It
68 * relies on px->tot_wact and px->tot_wbck, so it must be
69 * called after recount_servers(). It also expects px->srv_map
70 * to be initialized to the largest value needed.
71 */
72void recalc_server_map(struct proxy *px)
73{
74 int o, tot, flag;
75 struct server *cur, *best;
76
77 if (px->srv_act) {
78 flag = SRV_RUNNING;
79 tot = px->tot_wact;
80 } else if (px->srv_bck) {
81 flag = SRV_RUNNING | SRV_BACKUP;
82 if (px->options & PR_O_USE_ALL_BK)
83 tot = px->tot_wbck;
84 else
85 tot = 1; /* the first server is enough */
86 } else {
87 px->srv_map_sz = 0;
88 return;
89 }
90
91 /* this algorithm gives priority to the first server, which means that
92 * it will respect the declaration order for equivalent weights, and
93 * that whatever the weights, the first server called will always be
94 * the first declard. This is an important asumption for the backup
95 * case, where we want the first server only.
96 */
97 for (cur = px->srv; cur; cur = cur->next)
98 cur->wscore = 0;
99
100 for (o = 0; o < tot; o++) {
101 int max = 0;
102 best = NULL;
103 for (cur = px->srv; cur; cur = cur->next) {
104 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
105 int v;
106
107 /* If we are forced to return only one server, we don't want to
108 * go further, because we would return the wrong one due to
109 * divide overflow.
110 */
111 if (tot == 1) {
112 best = cur;
113 break;
114 }
115
116 cur->wscore += cur->eweight + 1;
117 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
118 if (best == NULL || v > max) {
119 max = v;
120 best = cur;
121 }
122 }
123 }
124 px->srv_map[o] = best;
125 best->wscore -= tot;
126 }
127 px->srv_map_sz = tot;
128}
129
130
131/*
132 * This function marks the session as 'assigned' in direct or dispatch modes,
133 * or tries to assign one in balance mode, according to the algorithm. It does
134 * nothing if the session had already been assigned a server.
135 *
136 * It may return :
137 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
138 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
139 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
140 * SRV_STATUS_INTERNAL for other unrecoverable errors.
141 *
142 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
143 * not need to be called anymore. This usually means that s->srv can be trusted
144 * in balance and direct modes. This flag is not cleared, so it's to the caller
145 * to clear it if required (eg: redispatch).
146 *
147 */
148
149int assign_server(struct session *s)
150{
151#ifdef DEBUG_FULL
152 fprintf(stderr,"assign_server : s=%p\n",s);
153#endif
154
155 if (s->pend_pos)
156 return SRV_STATUS_INTERNAL;
157
158 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreau830ff452006-12-17 19:31:23 +0100159 if ((s->be->beprm->options & PR_O_BALANCE) && !(s->flags & SN_DIRECT)) {
160 if (!s->be->beprm->srv_act && !s->be->beprm->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200161 return SRV_STATUS_NOSRV;
162
Willy Tarreau830ff452006-12-17 19:31:23 +0100163 if (s->be->beprm->options & PR_O_BALANCE_RR) {
164 s->srv = get_server_rr_with_conns(s->be->beprm);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200165 if (!s->srv)
166 return SRV_STATUS_FULL;
167 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100168 else if (s->be->beprm->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200169 int len;
170
171 if (s->cli_addr.ss_family == AF_INET)
172 len = 4;
173 else if (s->cli_addr.ss_family == AF_INET6)
174 len = 16;
175 else /* unknown IP family */
176 return SRV_STATUS_INTERNAL;
177
Willy Tarreau830ff452006-12-17 19:31:23 +0100178 s->srv = get_server_sh(s->be->beprm,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200179 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
180 len);
181 }
182 else /* unknown balancing algorithm */
183 return SRV_STATUS_INTERNAL;
184 }
185 s->flags |= SN_ASSIGNED;
186 }
187 return SRV_STATUS_OK;
188}
189
190
191/*
192 * This function assigns a server address to a session, and sets SN_ADDR_SET.
193 * The address is taken from the currently assigned server, or from the
194 * dispatch or transparent address.
195 *
196 * It may return :
197 * SRV_STATUS_OK if everything is OK.
198 * SRV_STATUS_INTERNAL for other unrecoverable errors.
199 *
200 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
201 * not cleared, so it's to the caller to clear it if required.
202 *
203 */
204int assign_server_address(struct session *s)
205{
206#ifdef DEBUG_FULL
207 fprintf(stderr,"assign_server_address : s=%p\n",s);
208#endif
209
Willy Tarreau830ff452006-12-17 19:31:23 +0100210 if (s->flags & SN_DIRECT || s->be->beprm->options & PR_O_BALANCE) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200211 /* A server is necessarily known for this session */
212 if (!(s->flags & SN_ASSIGNED))
213 return SRV_STATUS_INTERNAL;
214
215 s->srv_addr = s->srv->addr;
216
217 /* if this server remaps proxied ports, we'll use
218 * the port the client connected to with an offset. */
219 if (s->srv->state & SRV_MAPPORTS) {
220 struct sockaddr_in sockname;
221 socklen_t namelen = sizeof(sockname);
222
Willy Tarreau73de9892006-11-30 11:40:23 +0100223 if (!(s->fe->options & PR_O_TRANSP) ||
Willy Tarreaubaaee002006-06-26 02:48:02 +0200224 get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
225 getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen);
226 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
227 }
228 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100229 else if (*(int *)&s->be->beprm->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200230 /* connect to the defined dispatch addr */
Willy Tarreau830ff452006-12-17 19:31:23 +0100231 s->srv_addr = s->be->beprm->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200232 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100233 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200234 /* in transparent mode, use the original dest addr if no dispatch specified */
235 socklen_t salen = sizeof(s->srv_addr);
236
237 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
238 qfprintf(stderr, "Cannot get original server address.\n");
239 return SRV_STATUS_INTERNAL;
240 }
241 }
242
243 s->flags |= SN_ADDR_SET;
244 return SRV_STATUS_OK;
245}
246
247
248/* This function assigns a server to session <s> if required, and can add the
249 * connection to either the assigned server's queue or to the proxy's queue.
250 *
251 * Returns :
252 *
253 * SRV_STATUS_OK if everything is OK.
254 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
255 * SRV_STATUS_QUEUED if the connection has been queued.
256 * SRV_STATUS_FULL if the server(s) is/are saturated and the
257 * connection could not be queued.
258 * SRV_STATUS_INTERNAL for other unrecoverable errors.
259 *
260 */
261int assign_server_and_queue(struct session *s)
262{
263 struct pendconn *p;
264 int err;
265
266 if (s->pend_pos)
267 return SRV_STATUS_INTERNAL;
268
269 if (s->flags & SN_ASSIGNED) {
270 /* a server does not need to be assigned, perhaps because we're in
271 * direct mode, or in dispatch or transparent modes where the server
272 * is not needed.
273 */
274 if (s->srv &&
275 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
276 p = pendconn_add(s);
277 if (p)
278 return SRV_STATUS_QUEUED;
279 else
280 return SRV_STATUS_FULL;
281 }
282 return SRV_STATUS_OK;
283 }
284
285 /* a server needs to be assigned */
286 err = assign_server(s);
287 switch (err) {
288 case SRV_STATUS_OK:
289 /* in balance mode, we might have servers with connection limits */
290 if (s->srv &&
291 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
292 p = pendconn_add(s);
293 if (p)
294 return SRV_STATUS_QUEUED;
295 else
296 return SRV_STATUS_FULL;
297 }
298 return SRV_STATUS_OK;
299
300 case SRV_STATUS_FULL:
301 /* queue this session into the proxy's queue */
302 p = pendconn_add(s);
303 if (p)
304 return SRV_STATUS_QUEUED;
305 else
306 return SRV_STATUS_FULL;
307
308 case SRV_STATUS_NOSRV:
309 case SRV_STATUS_INTERNAL:
310 return err;
311 default:
312 return SRV_STATUS_INTERNAL;
313 }
314}
315
316
317/*
318 * This function initiates a connection to the server assigned to this session
319 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
320 * It can return one of :
321 * - SN_ERR_NONE if everything's OK
322 * - SN_ERR_SRVTO if there are no more servers
323 * - SN_ERR_SRVCL if the connection was refused by the server
324 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
325 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
326 * - SN_ERR_INTERNAL for any other purely internal errors
327 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
328 */
329int connect_server(struct session *s)
330{
331 int fd, err;
332
333 if (!(s->flags & SN_ADDR_SET)) {
334 err = assign_server_address(s);
335 if (err != SRV_STATUS_OK)
336 return SN_ERR_INTERNAL;
337 }
338
339 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
340 qfprintf(stderr, "Cannot get a server socket.\n");
341
342 if (errno == ENFILE)
Willy Tarreau830ff452006-12-17 19:31:23 +0100343 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200344 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100345 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200346 else if (errno == EMFILE)
Willy Tarreau830ff452006-12-17 19:31:23 +0100347 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200348 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100349 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200350 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreau830ff452006-12-17 19:31:23 +0100351 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200352 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100353 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200354 /* this is a resource error */
355 return SN_ERR_RESOURCE;
356 }
357
358 if (fd >= global.maxsock) {
359 /* do not log anything there, it's a normal condition when this option
360 * is used to serialize connections to a server !
361 */
362 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
363 close(fd);
364 return SN_ERR_PRXCOND; /* it is a configuration limit */
365 }
366
367 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
368 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
369 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
370 close(fd);
371 return SN_ERR_INTERNAL;
372 }
373
Willy Tarreau830ff452006-12-17 19:31:23 +0100374 if (s->be->beprm->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200375 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
376
377 /* allow specific binding :
378 * - server-specific at first
379 * - proxy-specific next
380 */
381 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
382 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
383 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
384 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100385 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200386 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100387 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200388 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100389 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200390 return SN_ERR_RESOURCE;
391 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100392#ifdef CONFIG_HAP_CTTPROXY
393 if (s->srv->state & SRV_TPROXY_MASK) {
394 struct in_tproxy itp1, itp2;
395 memset(&itp1, 0, sizeof(itp1));
396
397 itp1.op = TPROXY_ASSIGN;
398 switch (s->srv->state & SRV_TPROXY_MASK) {
399 case SRV_TPROXY_ADDR:
400 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
401 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
402 break;
403 case SRV_TPROXY_CLI:
404 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
405 /* fall through */
406 case SRV_TPROXY_CIP:
407 /* FIXME: what can we do if the client connects in IPv6 ? */
408 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
409 break;
410 }
411
412 /* set connect flag on socket */
413 itp2.op = TPROXY_FLAGS;
414 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
415
416 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
417 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
418 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100419 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100420 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100421 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100422 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100423 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100424 return SN_ERR_RESOURCE;
425 }
426 }
427#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200428 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100429 else if (s->be->beprm->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200430 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreau830ff452006-12-17 19:31:23 +0100431 if (bind(fd, (struct sockaddr *)&s->be->beprm->source_addr, sizeof(s->be->beprm->source_addr)) == -1) {
432 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->beprm->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200433 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100434 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200435 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100436 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200437 return SN_ERR_RESOURCE;
438 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100439#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreau830ff452006-12-17 19:31:23 +0100440 if (s->be->beprm->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100441 struct in_tproxy itp1, itp2;
442 memset(&itp1, 0, sizeof(itp1));
443
444 itp1.op = TPROXY_ASSIGN;
Willy Tarreau830ff452006-12-17 19:31:23 +0100445 switch (s->be->beprm->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100446 case PR_O_TPXY_ADDR:
447 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
448 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
449 break;
450 case PR_O_TPXY_CLI:
451 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
452 /* fall through */
453 case PR_O_TPXY_CIP:
454 /* FIXME: what can we do if the client connects in IPv6 ? */
455 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
456 break;
457 }
458
459 /* set connect flag on socket */
460 itp2.op = TPROXY_FLAGS;
461 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
462
463 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
464 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
465 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100466 s->be->beprm->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100467 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100468 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100469 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100470 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100471 return SN_ERR_RESOURCE;
472 }
473 }
474#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200475 }
476
477 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
478 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
479
480 if (errno == EAGAIN || errno == EADDRINUSE) {
481 char *msg;
482 if (errno == EAGAIN) /* no free ports left, try again later */
483 msg = "no free ports";
484 else
485 msg = "local address already in use";
486
487 qfprintf(stderr,"Cannot connect: %s.\n",msg);
488 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100489 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200490 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100491 s->be->beprm->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200492 return SN_ERR_RESOURCE;
493 } else if (errno == ETIMEDOUT) {
494 //qfprintf(stderr,"Connect(): ETIMEDOUT");
495 close(fd);
496 return SN_ERR_SRVTO;
497 } else {
498 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
499 //qfprintf(stderr,"Connect(): %d", errno);
500 close(fd);
501 return SN_ERR_SRVCL;
502 }
503 }
504
505 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200506 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200507 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200508 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200509 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200510 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200511
Willy Tarreau2a429502006-10-15 14:52:29 +0200512 MY_FD_SET(fd, StaticWriteEvent); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200513#if defined(DEBUG_FULL) && defined(ENABLE_EPOLL)
514 if (PrevReadEvent) {
Willy Tarreau2a429502006-10-15 14:52:29 +0200515 assert(!(MY_FD_ISSET(fd, PrevReadEvent)));
516 assert(!(MY_FD_ISSET(fd, PrevWriteEvent)));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200517 }
518#endif
519
520 fd_insert(fd);
521 if (s->srv) {
522 s->srv->cur_sess++;
523 if (s->srv->cur_sess > s->srv->cur_sess_max)
524 s->srv->cur_sess_max = s->srv->cur_sess;
525 }
526
Willy Tarreau830ff452006-12-17 19:31:23 +0100527 if (s->be->beprm->contimeout)
528 tv_delayfrom(&s->req->cex, &now, s->be->beprm->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200529 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200530 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200531 return SN_ERR_NONE; /* connection is OK */
532}
533
534
535/*
536 * This function checks the retry count during the connect() job.
537 * It updates the session's srv_state and retries, so that the caller knows
538 * what it has to do. It uses the last connection error to set the log when
539 * it expires. It returns 1 when it has expired, and 0 otherwise.
540 */
541int srv_count_retry_down(struct session *t, int conn_err)
542{
543 /* we are in front of a retryable error */
544 t->conn_retries--;
545 if (t->conn_retries < 0) {
546 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200547 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200548 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100549 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200550 if (t->srv)
551 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100552 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200553
554 /* We used to have a free connection slot. Since we'll never use it,
555 * we have to inform the server that it may be used by another session.
556 */
Willy Tarreau830ff452006-12-17 19:31:23 +0100557 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200558 task_wakeup(&rq, t->srv->queue_mgt);
559 return 1;
560 }
561 return 0;
562}
563
564
565/*
566 * This function performs the retryable part of the connect() job.
567 * It updates the session's srv_state and retries, so that the caller knows
568 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
569 * it needs to redispatch.
570 */
571int srv_retryable_connect(struct session *t)
572{
573 int conn_err;
574
575 /* This loop ensures that we stop before the last retry in case of a
576 * redispatchable server.
577 */
578 do {
579 /* initiate a connection to the server */
580 conn_err = connect_server(t);
581 switch (conn_err) {
582
583 case SN_ERR_NONE:
584 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
585 t->srv_state = SV_STCONN;
586 return 1;
587
588 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200589 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200590 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100591 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200592 if (t->srv)
593 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100594 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200595 /* release other sessions waiting for this server */
Willy Tarreau830ff452006-12-17 19:31:23 +0100596 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200597 task_wakeup(&rq, t->srv->queue_mgt);
598 return 1;
599 }
600 /* ensure that we have enough retries left */
601 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200602 return 1;
603 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100604 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->beprm->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200605
606 /* We're on our last chance, and the REDISP option was specified.
607 * We will ignore cookie and force to balance or use the dispatcher.
608 */
609 /* let's try to offer this slot to anybody */
Willy Tarreau830ff452006-12-17 19:31:23 +0100610 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200611 task_wakeup(&rq, t->srv->queue_mgt);
612
613 if (t->srv)
614 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100615 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200616
617 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
618 t->srv = NULL; /* it's left to the dispatcher to choose a server */
619 if ((t->flags & SN_CK_MASK) == SN_CK_VALID) {
620 t->flags &= ~SN_CK_MASK;
621 t->flags |= SN_CK_DOWN;
622 }
623 return 0;
624}
625
626
627/* This function performs the "redispatch" part of a connection attempt. It
628 * will assign a server if required, queue the connection if required, and
629 * handle errors that might arise at this level. It can change the server
630 * state. It will return 1 if it encounters an error, switches the server
631 * state, or has to queue a connection. Otherwise, it will return 0 indicating
632 * that the connection is ready to use.
633 */
634
635int srv_redispatch_connect(struct session *t)
636{
637 int conn_err;
638
639 /* We know that we don't have any connection pending, so we will
640 * try to get a new one, and wait in this state if it's queued
641 */
642 conn_err = assign_server_and_queue(t);
643 switch (conn_err) {
644 case SRV_STATUS_OK:
645 break;
646
647 case SRV_STATUS_NOSRV:
648 /* note: it is guaranteed that t->srv == NULL here */
Willy Tarreaud7971282006-07-29 18:36:34 +0200649 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200650 srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100651 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200652 if (t->srv)
653 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100654 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200655
656 return 1;
657
658 case SRV_STATUS_QUEUED:
659 /* FIXME-20060503 : we should use the queue timeout instead */
Willy Tarreau830ff452006-12-17 19:31:23 +0100660 if (t->be->beprm->contimeout)
661 tv_delayfrom(&t->req->cex, &now, t->be->beprm->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200662 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200663 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200664 t->srv_state = SV_STIDLE;
665 /* do nothing else and do not wake any other session up */
666 return 1;
667
668 case SRV_STATUS_FULL:
669 case SRV_STATUS_INTERNAL:
670 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200671 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200672 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100673 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200674 if (t->srv)
675 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100676 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200677
678 /* release other sessions waiting for this server */
Willy Tarreau830ff452006-12-17 19:31:23 +0100679 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200680 task_wakeup(&rq, t->srv->queue_mgt);
681 return 1;
682 }
683 /* if we get here, it's because we got SRV_STATUS_OK, which also
684 * means that the connection has not been queued.
685 */
686 return 0;
687}
688
689
690/*
691 * Local variables:
692 * c-indent-level: 8
693 * c-basic-offset: 8
694 * End:
695 */