blob: 68f2925761eb1e4dcfe2952669a1a1114202be85 [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
Willy Tarreau6d1a9882007-01-07 02:03:04 +010044#ifdef CONFIG_HAP_TCPSPLICE
45#include <libtcpsplice.h>
46#endif
47
Willy Tarreaubaaee002006-06-26 02:48:02 +020048/*
49 * This function recounts the number of usable active and backup servers for
50 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
51 * This function also recomputes the total active and backup weights.
52 */
53void recount_servers(struct proxy *px)
54{
55 struct server *srv;
56
57 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
58 for (srv = px->srv; srv != NULL; srv = srv->next) {
59 if (srv->state & SRV_RUNNING) {
60 if (srv->state & SRV_BACKUP) {
61 px->srv_bck++;
62 px->tot_wbck += srv->eweight + 1;
63 } else {
64 px->srv_act++;
65 px->tot_wact += srv->eweight + 1;
66 }
67 }
68 }
69}
70
71/* This function recomputes the server map for proxy px. It
72 * relies on px->tot_wact and px->tot_wbck, so it must be
73 * called after recount_servers(). It also expects px->srv_map
74 * to be initialized to the largest value needed.
75 */
76void recalc_server_map(struct proxy *px)
77{
78 int o, tot, flag;
79 struct server *cur, *best;
80
81 if (px->srv_act) {
82 flag = SRV_RUNNING;
83 tot = px->tot_wact;
84 } else if (px->srv_bck) {
85 flag = SRV_RUNNING | SRV_BACKUP;
86 if (px->options & PR_O_USE_ALL_BK)
87 tot = px->tot_wbck;
88 else
89 tot = 1; /* the first server is enough */
90 } else {
91 px->srv_map_sz = 0;
92 return;
93 }
94
95 /* this algorithm gives priority to the first server, which means that
96 * it will respect the declaration order for equivalent weights, and
97 * that whatever the weights, the first server called will always be
98 * the first declard. This is an important asumption for the backup
99 * case, where we want the first server only.
100 */
101 for (cur = px->srv; cur; cur = cur->next)
102 cur->wscore = 0;
103
104 for (o = 0; o < tot; o++) {
105 int max = 0;
106 best = NULL;
107 for (cur = px->srv; cur; cur = cur->next) {
108 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
109 int v;
110
111 /* If we are forced to return only one server, we don't want to
112 * go further, because we would return the wrong one due to
113 * divide overflow.
114 */
115 if (tot == 1) {
116 best = cur;
117 break;
118 }
119
120 cur->wscore += cur->eweight + 1;
121 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
122 if (best == NULL || v > max) {
123 max = v;
124 best = cur;
125 }
126 }
127 }
128 px->srv_map[o] = best;
129 best->wscore -= tot;
130 }
131 px->srv_map_sz = tot;
132}
133
134
135/*
136 * This function marks the session as 'assigned' in direct or dispatch modes,
137 * or tries to assign one in balance mode, according to the algorithm. It does
138 * nothing if the session had already been assigned a server.
139 *
140 * It may return :
141 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
142 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
143 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
144 * SRV_STATUS_INTERNAL for other unrecoverable errors.
145 *
146 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
147 * not need to be called anymore. This usually means that s->srv can be trusted
148 * in balance and direct modes. This flag is not cleared, so it's to the caller
149 * to clear it if required (eg: redispatch).
150 *
151 */
152
153int assign_server(struct session *s)
154{
155#ifdef DEBUG_FULL
156 fprintf(stderr,"assign_server : s=%p\n",s);
157#endif
158
159 if (s->pend_pos)
160 return SRV_STATUS_INTERNAL;
161
162 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100163 if (s->be->beprm->options & PR_O_BALANCE) {
164 if (s->flags & SN_DIRECT) {
165 s->flags |= SN_ASSIGNED;
166 return SRV_STATUS_OK;
167 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100168 if (!s->be->beprm->srv_act && !s->be->beprm->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200169 return SRV_STATUS_NOSRV;
170
Willy Tarreau830ff452006-12-17 19:31:23 +0100171 if (s->be->beprm->options & PR_O_BALANCE_RR) {
172 s->srv = get_server_rr_with_conns(s->be->beprm);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200173 if (!s->srv)
174 return SRV_STATUS_FULL;
175 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100176 else if (s->be->beprm->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200177 int len;
178
179 if (s->cli_addr.ss_family == AF_INET)
180 len = 4;
181 else if (s->cli_addr.ss_family == AF_INET6)
182 len = 16;
183 else /* unknown IP family */
184 return SRV_STATUS_INTERNAL;
185
Willy Tarreau830ff452006-12-17 19:31:23 +0100186 s->srv = get_server_sh(s->be->beprm,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200187 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
188 len);
189 }
190 else /* unknown balancing algorithm */
191 return SRV_STATUS_INTERNAL;
192 }
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100193 else if (!*(int *)&s->be->beprm->dispatch_addr.sin_addr &&
194 !(s->fe->options & PR_O_TRANSP)) {
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100195 return SRV_STATUS_NOSRV;
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100196 }
197 s->flags |= SN_ASSIGNED;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200198 }
199 return SRV_STATUS_OK;
200}
201
202
203/*
204 * This function assigns a server address to a session, and sets SN_ADDR_SET.
205 * The address is taken from the currently assigned server, or from the
206 * dispatch or transparent address.
207 *
208 * It may return :
209 * SRV_STATUS_OK if everything is OK.
210 * SRV_STATUS_INTERNAL for other unrecoverable errors.
211 *
212 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
213 * not cleared, so it's to the caller to clear it if required.
214 *
215 */
216int assign_server_address(struct session *s)
217{
218#ifdef DEBUG_FULL
219 fprintf(stderr,"assign_server_address : s=%p\n",s);
220#endif
221
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100222 if ((s->flags & SN_DIRECT) || (s->be->beprm->options & PR_O_BALANCE)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200223 /* A server is necessarily known for this session */
224 if (!(s->flags & SN_ASSIGNED))
225 return SRV_STATUS_INTERNAL;
226
227 s->srv_addr = s->srv->addr;
228
229 /* if this server remaps proxied ports, we'll use
230 * the port the client connected to with an offset. */
231 if (s->srv->state & SRV_MAPPORTS) {
232 struct sockaddr_in sockname;
233 socklen_t namelen = sizeof(sockname);
234
Willy Tarreau73de9892006-11-30 11:40:23 +0100235 if (!(s->fe->options & PR_O_TRANSP) ||
Willy Tarreaubaaee002006-06-26 02:48:02 +0200236 get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
237 getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen);
238 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
239 }
240 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100241 else if (*(int *)&s->be->beprm->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242 /* connect to the defined dispatch addr */
Willy Tarreau830ff452006-12-17 19:31:23 +0100243 s->srv_addr = s->be->beprm->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200244 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100245 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200246 /* in transparent mode, use the original dest addr if no dispatch specified */
247 socklen_t salen = sizeof(s->srv_addr);
248
249 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
250 qfprintf(stderr, "Cannot get original server address.\n");
251 return SRV_STATUS_INTERNAL;
252 }
253 }
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100254 else {
255 /* no server and no LB algorithm ! */
256 return SRV_STATUS_INTERNAL;
257 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200258
259 s->flags |= SN_ADDR_SET;
260 return SRV_STATUS_OK;
261}
262
263
264/* This function assigns a server to session <s> if required, and can add the
265 * connection to either the assigned server's queue or to the proxy's queue.
266 *
267 * Returns :
268 *
269 * SRV_STATUS_OK if everything is OK.
270 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
271 * SRV_STATUS_QUEUED if the connection has been queued.
272 * SRV_STATUS_FULL if the server(s) is/are saturated and the
273 * connection could not be queued.
274 * SRV_STATUS_INTERNAL for other unrecoverable errors.
275 *
276 */
277int assign_server_and_queue(struct session *s)
278{
279 struct pendconn *p;
280 int err;
281
282 if (s->pend_pos)
283 return SRV_STATUS_INTERNAL;
284
285 if (s->flags & SN_ASSIGNED) {
286 /* a server does not need to be assigned, perhaps because we're in
287 * direct mode, or in dispatch or transparent modes where the server
288 * is not needed.
289 */
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
301 /* a server needs to be assigned */
302 err = assign_server(s);
303 switch (err) {
304 case SRV_STATUS_OK:
305 /* in balance mode, we might have servers with connection limits */
306 if (s->srv &&
307 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
308 p = pendconn_add(s);
309 if (p)
310 return SRV_STATUS_QUEUED;
311 else
312 return SRV_STATUS_FULL;
313 }
314 return SRV_STATUS_OK;
315
316 case SRV_STATUS_FULL:
317 /* queue this session into the proxy's queue */
318 p = pendconn_add(s);
319 if (p)
320 return SRV_STATUS_QUEUED;
321 else
322 return SRV_STATUS_FULL;
323
324 case SRV_STATUS_NOSRV:
325 case SRV_STATUS_INTERNAL:
326 return err;
327 default:
328 return SRV_STATUS_INTERNAL;
329 }
330}
331
332
333/*
334 * This function initiates a connection to the server assigned to this session
335 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
336 * It can return one of :
337 * - SN_ERR_NONE if everything's OK
338 * - SN_ERR_SRVTO if there are no more servers
339 * - SN_ERR_SRVCL if the connection was refused by the server
340 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
341 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
342 * - SN_ERR_INTERNAL for any other purely internal errors
343 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
344 */
345int connect_server(struct session *s)
346{
347 int fd, err;
348
349 if (!(s->flags & SN_ADDR_SET)) {
350 err = assign_server_address(s);
351 if (err != SRV_STATUS_OK)
352 return SN_ERR_INTERNAL;
353 }
354
355 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
356 qfprintf(stderr, "Cannot get a server socket.\n");
357
358 if (errno == ENFILE)
Willy Tarreau830ff452006-12-17 19:31:23 +0100359 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200360 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100361 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200362 else if (errno == EMFILE)
Willy Tarreau830ff452006-12-17 19:31:23 +0100363 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200364 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100365 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200366 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreau830ff452006-12-17 19:31:23 +0100367 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200368 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100369 s->be->beprm->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200370 /* this is a resource error */
371 return SN_ERR_RESOURCE;
372 }
373
374 if (fd >= global.maxsock) {
375 /* do not log anything there, it's a normal condition when this option
376 * is used to serialize connections to a server !
377 */
378 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
379 close(fd);
380 return SN_ERR_PRXCOND; /* it is a configuration limit */
381 }
382
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100383#ifdef CONFIG_HAP_TCPSPLICE
384 if ((s->fe->options & s->be->beprm->options) & PR_O_TCPSPLICE) {
385 /* TCP splicing supported by both FE and BE */
386 tcp_splice_initfd(s->cli_fd, fd);
387 }
388#endif
389
Willy Tarreaubaaee002006-06-26 02:48:02 +0200390 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
391 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
392 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
393 close(fd);
394 return SN_ERR_INTERNAL;
395 }
396
Willy Tarreau830ff452006-12-17 19:31:23 +0100397 if (s->be->beprm->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200398 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
399
400 /* allow specific binding :
401 * - server-specific at first
402 * - proxy-specific next
403 */
404 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
405 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
406 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
407 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100408 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200409 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100410 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200411 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100412 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200413 return SN_ERR_RESOURCE;
414 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100415#ifdef CONFIG_HAP_CTTPROXY
416 if (s->srv->state & SRV_TPROXY_MASK) {
417 struct in_tproxy itp1, itp2;
418 memset(&itp1, 0, sizeof(itp1));
419
420 itp1.op = TPROXY_ASSIGN;
421 switch (s->srv->state & SRV_TPROXY_MASK) {
422 case SRV_TPROXY_ADDR:
423 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
424 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
425 break;
426 case SRV_TPROXY_CLI:
427 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
428 /* fall through */
429 case SRV_TPROXY_CIP:
430 /* FIXME: what can we do if the client connects in IPv6 ? */
431 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
432 break;
433 }
434
435 /* set connect flag on socket */
436 itp2.op = TPROXY_FLAGS;
437 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
438
439 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
440 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
441 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100442 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100443 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100444 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100445 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100446 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100447 return SN_ERR_RESOURCE;
448 }
449 }
450#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200451 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100452 else if (s->be->beprm->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200453 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreau830ff452006-12-17 19:31:23 +0100454 if (bind(fd, (struct sockaddr *)&s->be->beprm->source_addr, sizeof(s->be->beprm->source_addr)) == -1) {
455 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->beprm->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200456 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100457 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200458 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100459 s->be->beprm->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200460 return SN_ERR_RESOURCE;
461 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100462#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreau830ff452006-12-17 19:31:23 +0100463 if (s->be->beprm->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100464 struct in_tproxy itp1, itp2;
465 memset(&itp1, 0, sizeof(itp1));
466
467 itp1.op = TPROXY_ASSIGN;
Willy Tarreau830ff452006-12-17 19:31:23 +0100468 switch (s->be->beprm->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100469 case PR_O_TPXY_ADDR:
470 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
471 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
472 break;
473 case PR_O_TPXY_CLI:
474 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
475 /* fall through */
476 case PR_O_TPXY_CIP:
477 /* FIXME: what can we do if the client connects in IPv6 ? */
478 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
479 break;
480 }
481
482 /* set connect flag on socket */
483 itp2.op = TPROXY_FLAGS;
484 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
485
486 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
487 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
488 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100489 s->be->beprm->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100490 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100491 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100492 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100493 s->be->beprm->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100494 return SN_ERR_RESOURCE;
495 }
496 }
497#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200498 }
499
500 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
501 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
502
503 if (errno == EAGAIN || errno == EADDRINUSE) {
504 char *msg;
505 if (errno == EAGAIN) /* no free ports left, try again later */
506 msg = "no free ports";
507 else
508 msg = "local address already in use";
509
510 qfprintf(stderr,"Cannot connect: %s.\n",msg);
511 close(fd);
Willy Tarreau830ff452006-12-17 19:31:23 +0100512 send_log(s->be->beprm, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200513 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreau830ff452006-12-17 19:31:23 +0100514 s->be->beprm->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200515 return SN_ERR_RESOURCE;
516 } else if (errno == ETIMEDOUT) {
517 //qfprintf(stderr,"Connect(): ETIMEDOUT");
518 close(fd);
519 return SN_ERR_SRVTO;
520 } else {
521 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
522 //qfprintf(stderr,"Connect(): %d", errno);
523 close(fd);
524 return SN_ERR_SRVCL;
525 }
526 }
527
528 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200529 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200530 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200531 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200532 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200533 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200534
Willy Tarreau2a429502006-10-15 14:52:29 +0200535 MY_FD_SET(fd, StaticWriteEvent); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200536#if defined(DEBUG_FULL) && defined(ENABLE_EPOLL)
537 if (PrevReadEvent) {
Willy Tarreau2a429502006-10-15 14:52:29 +0200538 assert(!(MY_FD_ISSET(fd, PrevReadEvent)));
539 assert(!(MY_FD_ISSET(fd, PrevWriteEvent)));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200540 }
541#endif
542
543 fd_insert(fd);
544 if (s->srv) {
545 s->srv->cur_sess++;
546 if (s->srv->cur_sess > s->srv->cur_sess_max)
547 s->srv->cur_sess_max = s->srv->cur_sess;
548 }
549
Willy Tarreau830ff452006-12-17 19:31:23 +0100550 if (s->be->beprm->contimeout)
551 tv_delayfrom(&s->req->cex, &now, s->be->beprm->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200552 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200553 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200554 return SN_ERR_NONE; /* connection is OK */
555}
556
557
558/*
559 * This function checks the retry count during the connect() job.
560 * It updates the session's srv_state and retries, so that the caller knows
561 * what it has to do. It uses the last connection error to set the log when
562 * it expires. It returns 1 when it has expired, and 0 otherwise.
563 */
564int srv_count_retry_down(struct session *t, int conn_err)
565{
566 /* we are in front of a retryable error */
567 t->conn_retries--;
568 if (t->conn_retries < 0) {
569 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200570 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200571 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100572 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200573 if (t->srv)
574 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100575 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200576
577 /* We used to have a free connection slot. Since we'll never use it,
578 * we have to inform the server that it may be used by another session.
579 */
Willy Tarreau830ff452006-12-17 19:31:23 +0100580 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200581 task_wakeup(&rq, t->srv->queue_mgt);
582 return 1;
583 }
584 return 0;
585}
586
587
588/*
589 * This function performs the retryable part of the connect() job.
590 * It updates the session's srv_state and retries, so that the caller knows
591 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
592 * it needs to redispatch.
593 */
594int srv_retryable_connect(struct session *t)
595{
596 int conn_err;
597
598 /* This loop ensures that we stop before the last retry in case of a
599 * redispatchable server.
600 */
601 do {
602 /* initiate a connection to the server */
603 conn_err = connect_server(t);
604 switch (conn_err) {
605
606 case SN_ERR_NONE:
607 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
608 t->srv_state = SV_STCONN;
609 return 1;
610
611 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200612 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200613 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100614 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200615 if (t->srv)
616 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100617 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200618 /* release other sessions waiting for this server */
Willy Tarreau830ff452006-12-17 19:31:23 +0100619 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200620 task_wakeup(&rq, t->srv->queue_mgt);
621 return 1;
622 }
623 /* ensure that we have enough retries left */
624 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200625 return 1;
626 }
Willy Tarreau830ff452006-12-17 19:31:23 +0100627 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->beprm->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200628
629 /* We're on our last chance, and the REDISP option was specified.
630 * We will ignore cookie and force to balance or use the dispatcher.
631 */
632 /* let's try to offer this slot to anybody */
Willy Tarreau830ff452006-12-17 19:31:23 +0100633 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200634 task_wakeup(&rq, t->srv->queue_mgt);
635
636 if (t->srv)
637 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100638 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200639
640 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
641 t->srv = NULL; /* it's left to the dispatcher to choose a server */
642 if ((t->flags & SN_CK_MASK) == SN_CK_VALID) {
643 t->flags &= ~SN_CK_MASK;
644 t->flags |= SN_CK_DOWN;
645 }
646 return 0;
647}
648
649
650/* This function performs the "redispatch" part of a connection attempt. It
651 * will assign a server if required, queue the connection if required, and
652 * handle errors that might arise at this level. It can change the server
653 * state. It will return 1 if it encounters an error, switches the server
654 * state, or has to queue a connection. Otherwise, it will return 0 indicating
655 * that the connection is ready to use.
656 */
657
658int srv_redispatch_connect(struct session *t)
659{
660 int conn_err;
661
662 /* We know that we don't have any connection pending, so we will
663 * try to get a new one, and wait in this state if it's queued
664 */
665 conn_err = assign_server_and_queue(t);
666 switch (conn_err) {
667 case SRV_STATUS_OK:
668 break;
669
670 case SRV_STATUS_NOSRV:
671 /* note: it is guaranteed that t->srv == NULL here */
Willy Tarreaud7971282006-07-29 18:36:34 +0200672 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200673 srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100674 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200675 if (t->srv)
676 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100677 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200678
679 return 1;
680
681 case SRV_STATUS_QUEUED:
682 /* FIXME-20060503 : we should use the queue timeout instead */
Willy Tarreau830ff452006-12-17 19:31:23 +0100683 if (t->be->beprm->contimeout)
684 tv_delayfrom(&t->req->cex, &now, t->be->beprm->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200685 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200686 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200687 t->srv_state = SV_STIDLE;
688 /* do nothing else and do not wake any other session up */
689 return 1;
690
691 case SRV_STATUS_FULL:
692 case SRV_STATUS_INTERNAL:
693 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200694 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200695 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100696 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200697 if (t->srv)
698 t->srv->failed_conns++;
Willy Tarreau830ff452006-12-17 19:31:23 +0100699 t->be->beprm->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200700
701 /* release other sessions waiting for this server */
Willy Tarreau830ff452006-12-17 19:31:23 +0100702 if (may_dequeue_tasks(t->srv, t->be->beprm))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200703 task_wakeup(&rq, t->srv->queue_mgt);
704 return 1;
705 }
706 /* if we get here, it's because we got SRV_STATUS_OK, which also
707 * means that the connection has not been queued.
708 */
709 return 0;
710}
711
712
713/*
714 * Local variables:
715 * c-indent-level: 8
716 * c-basic-offset: 8
717 * End:
718 */