blob: e01068fd2685da9b4d2db63ac50a4c08c4b313cb [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>
33#include <proto/log.h>
34#include <proto/proto_http.h>
35#include <proto/queue.h>
36#include <proto/stream_sock.h>
37#include <proto/task.h>
38
Willy Tarreau77074d52006-11-12 23:57:19 +010039#ifdef CONFIG_HAP_CTTPROXY
40#include <import/ip_tproxy.h>
41#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +020042
43/*
44 * This function recounts the number of usable active and backup servers for
45 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
46 * This function also recomputes the total active and backup weights.
47 */
48void recount_servers(struct proxy *px)
49{
50 struct server *srv;
51
52 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
53 for (srv = px->srv; srv != NULL; srv = srv->next) {
54 if (srv->state & SRV_RUNNING) {
55 if (srv->state & SRV_BACKUP) {
56 px->srv_bck++;
57 px->tot_wbck += srv->eweight + 1;
58 } else {
59 px->srv_act++;
60 px->tot_wact += srv->eweight + 1;
61 }
62 }
63 }
64}
65
66/* This function recomputes the server map for proxy px. It
67 * relies on px->tot_wact and px->tot_wbck, so it must be
68 * called after recount_servers(). It also expects px->srv_map
69 * to be initialized to the largest value needed.
70 */
71void recalc_server_map(struct proxy *px)
72{
73 int o, tot, flag;
74 struct server *cur, *best;
75
76 if (px->srv_act) {
77 flag = SRV_RUNNING;
78 tot = px->tot_wact;
79 } else if (px->srv_bck) {
80 flag = SRV_RUNNING | SRV_BACKUP;
81 if (px->options & PR_O_USE_ALL_BK)
82 tot = px->tot_wbck;
83 else
84 tot = 1; /* the first server is enough */
85 } else {
86 px->srv_map_sz = 0;
87 return;
88 }
89
90 /* this algorithm gives priority to the first server, which means that
91 * it will respect the declaration order for equivalent weights, and
92 * that whatever the weights, the first server called will always be
93 * the first declard. This is an important asumption for the backup
94 * case, where we want the first server only.
95 */
96 for (cur = px->srv; cur; cur = cur->next)
97 cur->wscore = 0;
98
99 for (o = 0; o < tot; o++) {
100 int max = 0;
101 best = NULL;
102 for (cur = px->srv; cur; cur = cur->next) {
103 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
104 int v;
105
106 /* If we are forced to return only one server, we don't want to
107 * go further, because we would return the wrong one due to
108 * divide overflow.
109 */
110 if (tot == 1) {
111 best = cur;
112 break;
113 }
114
115 cur->wscore += cur->eweight + 1;
116 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
117 if (best == NULL || v > max) {
118 max = v;
119 best = cur;
120 }
121 }
122 }
123 px->srv_map[o] = best;
124 best->wscore -= tot;
125 }
126 px->srv_map_sz = tot;
127}
128
129
130/*
131 * This function marks the session as 'assigned' in direct or dispatch modes,
132 * or tries to assign one in balance mode, according to the algorithm. It does
133 * nothing if the session had already been assigned a server.
134 *
135 * It may return :
136 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
137 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
138 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
139 * SRV_STATUS_INTERNAL for other unrecoverable errors.
140 *
141 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
142 * not need to be called anymore. This usually means that s->srv can be trusted
143 * in balance and direct modes. This flag is not cleared, so it's to the caller
144 * to clear it if required (eg: redispatch).
145 *
146 */
147
148int assign_server(struct session *s)
149{
150#ifdef DEBUG_FULL
151 fprintf(stderr,"assign_server : s=%p\n",s);
152#endif
153
154 if (s->pend_pos)
155 return SRV_STATUS_INTERNAL;
156
157 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreau73de9892006-11-30 11:40:23 +0100158 if ((s->be->options & PR_O_BALANCE) && !(s->flags & SN_DIRECT)) {
159 if (!s->be->srv_act && !s->be->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200160 return SRV_STATUS_NOSRV;
161
Willy Tarreau73de9892006-11-30 11:40:23 +0100162 if (s->be->options & PR_O_BALANCE_RR) {
163 s->srv = get_server_rr_with_conns(s->be);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200164 if (!s->srv)
165 return SRV_STATUS_FULL;
166 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100167 else if (s->be->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200168 int len;
169
170 if (s->cli_addr.ss_family == AF_INET)
171 len = 4;
172 else if (s->cli_addr.ss_family == AF_INET6)
173 len = 16;
174 else /* unknown IP family */
175 return SRV_STATUS_INTERNAL;
176
Willy Tarreau73de9892006-11-30 11:40:23 +0100177 s->srv = get_server_sh(s->be,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200178 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
179 len);
180 }
181 else /* unknown balancing algorithm */
182 return SRV_STATUS_INTERNAL;
183 }
184 s->flags |= SN_ASSIGNED;
185 }
186 return SRV_STATUS_OK;
187}
188
189
190/*
191 * This function assigns a server address to a session, and sets SN_ADDR_SET.
192 * The address is taken from the currently assigned server, or from the
193 * dispatch or transparent address.
194 *
195 * It may return :
196 * SRV_STATUS_OK if everything is OK.
197 * SRV_STATUS_INTERNAL for other unrecoverable errors.
198 *
199 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
200 * not cleared, so it's to the caller to clear it if required.
201 *
202 */
203int assign_server_address(struct session *s)
204{
205#ifdef DEBUG_FULL
206 fprintf(stderr,"assign_server_address : s=%p\n",s);
207#endif
208
Willy Tarreau73de9892006-11-30 11:40:23 +0100209 if (s->flags & SN_DIRECT || s->be->options & PR_O_BALANCE) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200210 /* A server is necessarily known for this session */
211 if (!(s->flags & SN_ASSIGNED))
212 return SRV_STATUS_INTERNAL;
213
214 s->srv_addr = s->srv->addr;
215
216 /* if this server remaps proxied ports, we'll use
217 * the port the client connected to with an offset. */
218 if (s->srv->state & SRV_MAPPORTS) {
219 struct sockaddr_in sockname;
220 socklen_t namelen = sizeof(sockname);
221
Willy Tarreau73de9892006-11-30 11:40:23 +0100222 if (!(s->fe->options & PR_O_TRANSP) ||
Willy Tarreaubaaee002006-06-26 02:48:02 +0200223 get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
224 getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen);
225 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
226 }
227 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100228 else if (*(int *)&s->be->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200229 /* connect to the defined dispatch addr */
Willy Tarreau73de9892006-11-30 11:40:23 +0100230 s->srv_addr = s->be->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200231 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100232 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200233 /* in transparent mode, use the original dest addr if no dispatch specified */
234 socklen_t salen = sizeof(s->srv_addr);
235
236 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
237 qfprintf(stderr, "Cannot get original server address.\n");
238 return SRV_STATUS_INTERNAL;
239 }
240 }
241
242 s->flags |= SN_ADDR_SET;
243 return SRV_STATUS_OK;
244}
245
246
247/* This function assigns a server to session <s> if required, and can add the
248 * connection to either the assigned server's queue or to the proxy's queue.
249 *
250 * Returns :
251 *
252 * SRV_STATUS_OK if everything is OK.
253 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
254 * SRV_STATUS_QUEUED if the connection has been queued.
255 * SRV_STATUS_FULL if the server(s) is/are saturated and the
256 * connection could not be queued.
257 * SRV_STATUS_INTERNAL for other unrecoverable errors.
258 *
259 */
260int assign_server_and_queue(struct session *s)
261{
262 struct pendconn *p;
263 int err;
264
265 if (s->pend_pos)
266 return SRV_STATUS_INTERNAL;
267
268 if (s->flags & SN_ASSIGNED) {
269 /* a server does not need to be assigned, perhaps because we're in
270 * direct mode, or in dispatch or transparent modes where the server
271 * is not needed.
272 */
273 if (s->srv &&
274 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
275 p = pendconn_add(s);
276 if (p)
277 return SRV_STATUS_QUEUED;
278 else
279 return SRV_STATUS_FULL;
280 }
281 return SRV_STATUS_OK;
282 }
283
284 /* a server needs to be assigned */
285 err = assign_server(s);
286 switch (err) {
287 case SRV_STATUS_OK:
288 /* in balance mode, we might have servers with connection limits */
289 if (s->srv &&
290 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
291 p = pendconn_add(s);
292 if (p)
293 return SRV_STATUS_QUEUED;
294 else
295 return SRV_STATUS_FULL;
296 }
297 return SRV_STATUS_OK;
298
299 case SRV_STATUS_FULL:
300 /* queue this session into the proxy's queue */
301 p = pendconn_add(s);
302 if (p)
303 return SRV_STATUS_QUEUED;
304 else
305 return SRV_STATUS_FULL;
306
307 case SRV_STATUS_NOSRV:
308 case SRV_STATUS_INTERNAL:
309 return err;
310 default:
311 return SRV_STATUS_INTERNAL;
312 }
313}
314
315
316/*
317 * This function initiates a connection to the server assigned to this session
318 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
319 * It can return one of :
320 * - SN_ERR_NONE if everything's OK
321 * - SN_ERR_SRVTO if there are no more servers
322 * - SN_ERR_SRVCL if the connection was refused by the server
323 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
324 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
325 * - SN_ERR_INTERNAL for any other purely internal errors
326 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
327 */
328int connect_server(struct session *s)
329{
330 int fd, err;
331
332 if (!(s->flags & SN_ADDR_SET)) {
333 err = assign_server_address(s);
334 if (err != SRV_STATUS_OK)
335 return SN_ERR_INTERNAL;
336 }
337
338 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
339 qfprintf(stderr, "Cannot get a server socket.\n");
340
341 if (errno == ENFILE)
Willy Tarreau73de9892006-11-30 11:40:23 +0100342 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200343 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100344 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200345 else if (errno == EMFILE)
Willy Tarreau73de9892006-11-30 11:40:23 +0100346 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200347 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100348 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200349 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreau73de9892006-11-30 11:40:23 +0100350 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200351 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100352 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200353 /* this is a resource error */
354 return SN_ERR_RESOURCE;
355 }
356
357 if (fd >= global.maxsock) {
358 /* do not log anything there, it's a normal condition when this option
359 * is used to serialize connections to a server !
360 */
361 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
362 close(fd);
363 return SN_ERR_PRXCOND; /* it is a configuration limit */
364 }
365
366 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
367 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
368 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
369 close(fd);
370 return SN_ERR_INTERNAL;
371 }
372
Willy Tarreau73de9892006-11-30 11:40:23 +0100373 if (s->be->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200374 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
375
376 /* allow specific binding :
377 * - server-specific at first
378 * - proxy-specific next
379 */
380 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
381 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
382 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
383 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100384 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200385 close(fd);
Willy Tarreau73de9892006-11-30 11:40:23 +0100386 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200387 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100388 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200389 return SN_ERR_RESOURCE;
390 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100391#ifdef CONFIG_HAP_CTTPROXY
392 if (s->srv->state & SRV_TPROXY_MASK) {
393 struct in_tproxy itp1, itp2;
394 memset(&itp1, 0, sizeof(itp1));
395
396 itp1.op = TPROXY_ASSIGN;
397 switch (s->srv->state & SRV_TPROXY_MASK) {
398 case SRV_TPROXY_ADDR:
399 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
400 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
401 break;
402 case SRV_TPROXY_CLI:
403 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
404 /* fall through */
405 case SRV_TPROXY_CIP:
406 /* FIXME: what can we do if the client connects in IPv6 ? */
407 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
408 break;
409 }
410
411 /* set connect flag on socket */
412 itp2.op = TPROXY_FLAGS;
413 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
414
415 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
416 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
417 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100418 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100419 close(fd);
Willy Tarreau73de9892006-11-30 11:40:23 +0100420 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100421 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100422 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100423 return SN_ERR_RESOURCE;
424 }
425 }
426#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200427 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100428 else if (s->be->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200429 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreau73de9892006-11-30 11:40:23 +0100430 if (bind(fd, (struct sockaddr *)&s->be->source_addr, sizeof(s->be->source_addr)) == -1) {
431 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200432 close(fd);
Willy Tarreau73de9892006-11-30 11:40:23 +0100433 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200434 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100435 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200436 return SN_ERR_RESOURCE;
437 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100438#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreau73de9892006-11-30 11:40:23 +0100439 if (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100440 struct in_tproxy itp1, itp2;
441 memset(&itp1, 0, sizeof(itp1));
442
443 itp1.op = TPROXY_ASSIGN;
Willy Tarreau73de9892006-11-30 11:40:23 +0100444 switch (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100445 case PR_O_TPXY_ADDR:
446 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
447 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
448 break;
449 case PR_O_TPXY_CLI:
450 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
451 /* fall through */
452 case PR_O_TPXY_CIP:
453 /* FIXME: what can we do if the client connects in IPv6 ? */
454 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
455 break;
456 }
457
458 /* set connect flag on socket */
459 itp2.op = TPROXY_FLAGS;
460 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
461
462 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
463 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
464 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100465 s->be->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100466 close(fd);
Willy Tarreau73de9892006-11-30 11:40:23 +0100467 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100468 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100469 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100470 return SN_ERR_RESOURCE;
471 }
472 }
473#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200474 }
475
476 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
477 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
478
479 if (errno == EAGAIN || errno == EADDRINUSE) {
480 char *msg;
481 if (errno == EAGAIN) /* no free ports left, try again later */
482 msg = "no free ports";
483 else
484 msg = "local address already in use";
485
486 qfprintf(stderr,"Cannot connect: %s.\n",msg);
487 close(fd);
Willy Tarreau73de9892006-11-30 11:40:23 +0100488 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200489 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreau73de9892006-11-30 11:40:23 +0100490 s->be->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200491 return SN_ERR_RESOURCE;
492 } else if (errno == ETIMEDOUT) {
493 //qfprintf(stderr,"Connect(): ETIMEDOUT");
494 close(fd);
495 return SN_ERR_SRVTO;
496 } else {
497 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
498 //qfprintf(stderr,"Connect(): %d", errno);
499 close(fd);
500 return SN_ERR_SRVCL;
501 }
502 }
503
504 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200505 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200506 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200507 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200508 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200509 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200510
Willy Tarreau2a429502006-10-15 14:52:29 +0200511 MY_FD_SET(fd, StaticWriteEvent); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200512#if defined(DEBUG_FULL) && defined(ENABLE_EPOLL)
513 if (PrevReadEvent) {
Willy Tarreau2a429502006-10-15 14:52:29 +0200514 assert(!(MY_FD_ISSET(fd, PrevReadEvent)));
515 assert(!(MY_FD_ISSET(fd, PrevWriteEvent)));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200516 }
517#endif
518
519 fd_insert(fd);
520 if (s->srv) {
521 s->srv->cur_sess++;
522 if (s->srv->cur_sess > s->srv->cur_sess_max)
523 s->srv->cur_sess_max = s->srv->cur_sess;
524 }
525
Willy Tarreau73de9892006-11-30 11:40:23 +0100526 if (s->be->contimeout)
527 tv_delayfrom(&s->req->cex, &now, s->be->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200528 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200529 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200530 return SN_ERR_NONE; /* connection is OK */
531}
532
533
534/*
535 * This function checks the retry count during the connect() job.
536 * It updates the session's srv_state and retries, so that the caller knows
537 * what it has to do. It uses the last connection error to set the log when
538 * it expires. It returns 1 when it has expired, and 0 otherwise.
539 */
540int srv_count_retry_down(struct session *t, int conn_err)
541{
542 /* we are in front of a retryable error */
543 t->conn_retries--;
544 if (t->conn_retries < 0) {
545 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200546 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200547 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau73de9892006-11-30 11:40:23 +0100548 503, t->fe->errmsg.len503, t->fe->errmsg.msg503);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200549 if (t->srv)
550 t->srv->failed_conns++;
Willy Tarreau73de9892006-11-30 11:40:23 +0100551 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200552
553 /* We used to have a free connection slot. Since we'll never use it,
554 * we have to inform the server that it may be used by another session.
555 */
Willy Tarreau73de9892006-11-30 11:40:23 +0100556 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200557 task_wakeup(&rq, t->srv->queue_mgt);
558 return 1;
559 }
560 return 0;
561}
562
563
564/*
565 * This function performs the retryable part of the connect() job.
566 * It updates the session's srv_state and retries, so that the caller knows
567 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
568 * it needs to redispatch.
569 */
570int srv_retryable_connect(struct session *t)
571{
572 int conn_err;
573
574 /* This loop ensures that we stop before the last retry in case of a
575 * redispatchable server.
576 */
577 do {
578 /* initiate a connection to the server */
579 conn_err = connect_server(t);
580 switch (conn_err) {
581
582 case SN_ERR_NONE:
583 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
584 t->srv_state = SV_STCONN;
585 return 1;
586
587 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200588 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200589 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau73de9892006-11-30 11:40:23 +0100590 500, t->fe->errmsg.len500, t->fe->errmsg.msg500);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200591 if (t->srv)
592 t->srv->failed_conns++;
Willy Tarreau73de9892006-11-30 11:40:23 +0100593 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200594 /* release other sessions waiting for this server */
Willy Tarreau73de9892006-11-30 11:40:23 +0100595 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200596 task_wakeup(&rq, t->srv->queue_mgt);
597 return 1;
598 }
599 /* ensure that we have enough retries left */
600 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200601 return 1;
602 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100603 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200604
605 /* We're on our last chance, and the REDISP option was specified.
606 * We will ignore cookie and force to balance or use the dispatcher.
607 */
608 /* let's try to offer this slot to anybody */
Willy Tarreau73de9892006-11-30 11:40:23 +0100609 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200610 task_wakeup(&rq, t->srv->queue_mgt);
611
612 if (t->srv)
613 t->srv->failed_conns++;
Willy Tarreau73de9892006-11-30 11:40:23 +0100614 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200615
616 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
617 t->srv = NULL; /* it's left to the dispatcher to choose a server */
618 if ((t->flags & SN_CK_MASK) == SN_CK_VALID) {
619 t->flags &= ~SN_CK_MASK;
620 t->flags |= SN_CK_DOWN;
621 }
622 return 0;
623}
624
625
626/* This function performs the "redispatch" part of a connection attempt. It
627 * will assign a server if required, queue the connection if required, and
628 * handle errors that might arise at this level. It can change the server
629 * state. It will return 1 if it encounters an error, switches the server
630 * state, or has to queue a connection. Otherwise, it will return 0 indicating
631 * that the connection is ready to use.
632 */
633
634int srv_redispatch_connect(struct session *t)
635{
636 int conn_err;
637
638 /* We know that we don't have any connection pending, so we will
639 * try to get a new one, and wait in this state if it's queued
640 */
641 conn_err = assign_server_and_queue(t);
642 switch (conn_err) {
643 case SRV_STATUS_OK:
644 break;
645
646 case SRV_STATUS_NOSRV:
647 /* note: it is guaranteed that t->srv == NULL here */
Willy Tarreaud7971282006-07-29 18:36:34 +0200648 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200649 srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_C,
Willy Tarreau73de9892006-11-30 11:40:23 +0100650 503, t->fe->errmsg.len503, t->fe->errmsg.msg503);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200651 if (t->srv)
652 t->srv->failed_conns++;
Willy Tarreau73de9892006-11-30 11:40:23 +0100653 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200654
655 return 1;
656
657 case SRV_STATUS_QUEUED:
658 /* FIXME-20060503 : we should use the queue timeout instead */
Willy Tarreau73de9892006-11-30 11:40:23 +0100659 if (t->be->contimeout)
660 tv_delayfrom(&t->req->cex, &now, t->be->contimeout);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200661 else
Willy Tarreaud7971282006-07-29 18:36:34 +0200662 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200663 t->srv_state = SV_STIDLE;
664 /* do nothing else and do not wake any other session up */
665 return 1;
666
667 case SRV_STATUS_FULL:
668 case SRV_STATUS_INTERNAL:
669 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200670 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200671 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau73de9892006-11-30 11:40:23 +0100672 500, t->fe->errmsg.len500, t->fe->errmsg.msg500);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200673 if (t->srv)
674 t->srv->failed_conns++;
Willy Tarreau73de9892006-11-30 11:40:23 +0100675 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200676
677 /* release other sessions waiting for this server */
Willy Tarreau73de9892006-11-30 11:40:23 +0100678 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreaubaaee002006-06-26 02:48:02 +0200679 task_wakeup(&rq, t->srv->queue_mgt);
680 return 1;
681 }
682 /* if we get here, it's because we got SRV_STATUS_OK, which also
683 * means that the connection has not been queued.
684 */
685 return 0;
686}
687
688
689/*
690 * Local variables:
691 * c-indent-level: 8
692 * c-basic-offset: 8
693 * End:
694 */