blob: da8b8ac36a92e0811d92124466300ee550f68bb2 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Backend 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 <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>
Willy Tarreau14c8aac2007-05-08 19:46:30 +020032#include <proto/client.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020033#include <proto/fd.h>
Willy Tarreau80587432006-12-24 17:47:20 +010034#include <proto/httperr.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035#include <proto/log.h>
36#include <proto/proto_http.h>
37#include <proto/queue.h>
38#include <proto/stream_sock.h>
39#include <proto/task.h>
40
Willy Tarreau77074d52006-11-12 23:57:19 +010041#ifdef CONFIG_HAP_CTTPROXY
42#include <import/ip_tproxy.h>
43#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +020044
Willy Tarreau6d1a9882007-01-07 02:03:04 +010045#ifdef CONFIG_HAP_TCPSPLICE
46#include <libtcpsplice.h>
47#endif
48
Willy Tarreaubaaee002006-06-26 02:48:02 +020049/*
50 * This function recounts the number of usable active and backup servers for
51 * proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
52 * This function also recomputes the total active and backup weights.
53 */
54void recount_servers(struct proxy *px)
55{
56 struct server *srv;
57
58 px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
59 for (srv = px->srv; srv != NULL; srv = srv->next) {
60 if (srv->state & SRV_RUNNING) {
61 if (srv->state & SRV_BACKUP) {
62 px->srv_bck++;
Willy Tarreau417fae02007-03-25 21:16:40 +020063 px->tot_wbck += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020064 } else {
65 px->srv_act++;
Willy Tarreau417fae02007-03-25 21:16:40 +020066 px->tot_wact += srv->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +020067 }
68 }
69 }
70}
71
72/* This function recomputes the server map for proxy px. It
73 * relies on px->tot_wact and px->tot_wbck, so it must be
74 * called after recount_servers(). It also expects px->srv_map
75 * to be initialized to the largest value needed.
76 */
77void recalc_server_map(struct proxy *px)
78{
79 int o, tot, flag;
80 struct server *cur, *best;
81
82 if (px->srv_act) {
83 flag = SRV_RUNNING;
84 tot = px->tot_wact;
85 } else if (px->srv_bck) {
86 flag = SRV_RUNNING | SRV_BACKUP;
87 if (px->options & PR_O_USE_ALL_BK)
88 tot = px->tot_wbck;
89 else
90 tot = 1; /* the first server is enough */
91 } else {
92 px->srv_map_sz = 0;
Willy Tarreau5af3a692007-07-24 23:32:33 +020093 px->map_state &= ~PR_MAP_RECALC;
Willy Tarreaubaaee002006-06-26 02:48:02 +020094 return;
95 }
96
97 /* this algorithm gives priority to the first server, which means that
98 * it will respect the declaration order for equivalent weights, and
99 * that whatever the weights, the first server called will always be
100 * the first declard. This is an important asumption for the backup
101 * case, where we want the first server only.
102 */
103 for (cur = px->srv; cur; cur = cur->next)
104 cur->wscore = 0;
105
106 for (o = 0; o < tot; o++) {
107 int max = 0;
108 best = NULL;
109 for (cur = px->srv; cur; cur = cur->next) {
110 if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
111 int v;
112
113 /* If we are forced to return only one server, we don't want to
114 * go further, because we would return the wrong one due to
115 * divide overflow.
116 */
117 if (tot == 1) {
118 best = cur;
119 break;
120 }
121
Willy Tarreau417fae02007-03-25 21:16:40 +0200122 cur->wscore += cur->eweight;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200123 v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
124 if (best == NULL || v > max) {
125 max = v;
126 best = cur;
127 }
128 }
129 }
130 px->srv_map[o] = best;
131 best->wscore -= tot;
132 }
133 px->srv_map_sz = tot;
Willy Tarreau5af3a692007-07-24 23:32:33 +0200134 px->map_state &= ~PR_MAP_RECALC;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200135}
136
137
138/*
139 * This function marks the session as 'assigned' in direct or dispatch modes,
140 * or tries to assign one in balance mode, according to the algorithm. It does
141 * nothing if the session had already been assigned a server.
142 *
143 * It may return :
144 * SRV_STATUS_OK if everything is OK. s->srv will be valid.
145 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
146 * SRV_STATUS_FULL if all servers are saturated. s->srv = NULL.
147 * SRV_STATUS_INTERNAL for other unrecoverable errors.
148 *
149 * Upon successful return, the session flag SN_ASSIGNED to indicate that it does
150 * not need to be called anymore. This usually means that s->srv can be trusted
151 * in balance and direct modes. This flag is not cleared, so it's to the caller
152 * to clear it if required (eg: redispatch).
153 *
154 */
155
156int assign_server(struct session *s)
157{
158#ifdef DEBUG_FULL
159 fprintf(stderr,"assign_server : s=%p\n",s);
160#endif
161
162 if (s->pend_pos)
163 return SRV_STATUS_INTERNAL;
164
165 if (!(s->flags & SN_ASSIGNED)) {
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200166 if (s->be->options & PR_O_BALANCE) {
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100167 if (s->flags & SN_DIRECT) {
168 s->flags |= SN_ASSIGNED;
169 return SRV_STATUS_OK;
170 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200171 if (!s->be->srv_act && !s->be->srv_bck)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200172 return SRV_STATUS_NOSRV;
173
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200174 if (s->be->options & PR_O_BALANCE_RR) {
175 s->srv = get_server_rr_with_conns(s->be);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200176 if (!s->srv)
177 return SRV_STATUS_FULL;
178 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200179 else if (s->be->options & PR_O_BALANCE_SH) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200180 int len;
181
182 if (s->cli_addr.ss_family == AF_INET)
183 len = 4;
184 else if (s->cli_addr.ss_family == AF_INET6)
185 len = 16;
186 else /* unknown IP family */
187 return SRV_STATUS_INTERNAL;
188
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200189 s->srv = get_server_sh(s->be,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200190 (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
191 len);
192 }
Willy Tarreau2fcb5002007-05-08 13:35:26 +0200193 else if (s->be->options & PR_O_BALANCE_UH) {
194 /* URI hashing */
195 s->srv = get_server_uh(s->be,
196 s->txn.req.sol + s->txn.req.sl.rq.u,
197 s->txn.req.sl.rq.u_l);
198 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200199 else /* unknown balancing algorithm */
200 return SRV_STATUS_INTERNAL;
201 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200202 else if (!*(int *)&s->be->dispatch_addr.sin_addr &&
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100203 !(s->fe->options & PR_O_TRANSP)) {
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100204 return SRV_STATUS_NOSRV;
Willy Tarreau5d65bbb2007-01-21 12:47:26 +0100205 }
206 s->flags |= SN_ASSIGNED;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200207 }
208 return SRV_STATUS_OK;
209}
210
211
212/*
213 * This function assigns a server address to a session, and sets SN_ADDR_SET.
214 * The address is taken from the currently assigned server, or from the
215 * dispatch or transparent address.
216 *
217 * It may return :
218 * SRV_STATUS_OK if everything is OK.
219 * SRV_STATUS_INTERNAL for other unrecoverable errors.
220 *
221 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
222 * not cleared, so it's to the caller to clear it if required.
223 *
224 */
225int assign_server_address(struct session *s)
226{
227#ifdef DEBUG_FULL
228 fprintf(stderr,"assign_server_address : s=%p\n",s);
229#endif
230
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200231 if ((s->flags & SN_DIRECT) || (s->be->options & PR_O_BALANCE)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200232 /* A server is necessarily known for this session */
233 if (!(s->flags & SN_ASSIGNED))
234 return SRV_STATUS_INTERNAL;
235
236 s->srv_addr = s->srv->addr;
237
238 /* if this server remaps proxied ports, we'll use
239 * the port the client connected to with an offset. */
240 if (s->srv->state & SRV_MAPPORTS) {
Willy Tarreau14c8aac2007-05-08 19:46:30 +0200241 if (!(s->fe->options & PR_O_TRANSP) && !(s->flags & SN_FRT_ADDR_SET))
242 get_frt_addr(s);
243 if (s->frt_addr.ss_family == AF_INET) {
244 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
245 ntohs(((struct sockaddr_in *)&s->frt_addr)->sin_port));
246 } else {
247 s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
248 ntohs(((struct sockaddr_in6 *)&s->frt_addr)->sin6_port));
249 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250 }
251 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200252 else if (*(int *)&s->be->dispatch_addr.sin_addr) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200253 /* connect to the defined dispatch addr */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200254 s->srv_addr = s->be->dispatch_addr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200255 }
Willy Tarreau73de9892006-11-30 11:40:23 +0100256 else if (s->fe->options & PR_O_TRANSP) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200257 /* in transparent mode, use the original dest addr if no dispatch specified */
258 socklen_t salen = sizeof(s->srv_addr);
259
260 if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
261 qfprintf(stderr, "Cannot get original server address.\n");
262 return SRV_STATUS_INTERNAL;
263 }
264 }
Willy Tarreau1a1158b2007-01-20 11:07:46 +0100265 else {
266 /* no server and no LB algorithm ! */
267 return SRV_STATUS_INTERNAL;
268 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200269
270 s->flags |= SN_ADDR_SET;
271 return SRV_STATUS_OK;
272}
273
274
275/* This function assigns a server to session <s> if required, and can add the
276 * connection to either the assigned server's queue or to the proxy's queue.
277 *
278 * Returns :
279 *
280 * SRV_STATUS_OK if everything is OK.
281 * SRV_STATUS_NOSRV if no server is available. s->srv = NULL.
282 * SRV_STATUS_QUEUED if the connection has been queued.
283 * SRV_STATUS_FULL if the server(s) is/are saturated and the
284 * connection could not be queued.
285 * SRV_STATUS_INTERNAL for other unrecoverable errors.
286 *
287 */
288int assign_server_and_queue(struct session *s)
289{
290 struct pendconn *p;
291 int err;
292
293 if (s->pend_pos)
294 return SRV_STATUS_INTERNAL;
295
296 if (s->flags & SN_ASSIGNED) {
297 /* a server does not need to be assigned, perhaps because we're in
298 * direct mode, or in dispatch or transparent modes where the server
299 * is not needed.
300 */
301 if (s->srv &&
302 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
303 p = pendconn_add(s);
304 if (p)
305 return SRV_STATUS_QUEUED;
306 else
307 return SRV_STATUS_FULL;
308 }
309 return SRV_STATUS_OK;
310 }
311
312 /* a server needs to be assigned */
313 err = assign_server(s);
314 switch (err) {
315 case SRV_STATUS_OK:
316 /* in balance mode, we might have servers with connection limits */
317 if (s->srv &&
318 s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
319 p = pendconn_add(s);
320 if (p)
321 return SRV_STATUS_QUEUED;
322 else
323 return SRV_STATUS_FULL;
324 }
325 return SRV_STATUS_OK;
326
327 case SRV_STATUS_FULL:
328 /* queue this session into the proxy's queue */
329 p = pendconn_add(s);
330 if (p)
331 return SRV_STATUS_QUEUED;
332 else
333 return SRV_STATUS_FULL;
334
335 case SRV_STATUS_NOSRV:
336 case SRV_STATUS_INTERNAL:
337 return err;
338 default:
339 return SRV_STATUS_INTERNAL;
340 }
341}
342
343
344/*
345 * This function initiates a connection to the server assigned to this session
346 * (s->srv, s->srv_addr). It will assign a server if none is assigned yet.
347 * It can return one of :
348 * - SN_ERR_NONE if everything's OK
349 * - SN_ERR_SRVTO if there are no more servers
350 * - SN_ERR_SRVCL if the connection was refused by the server
351 * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
352 * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
353 * - SN_ERR_INTERNAL for any other purely internal errors
354 * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
355 */
356int connect_server(struct session *s)
357{
358 int fd, err;
359
360 if (!(s->flags & SN_ADDR_SET)) {
361 err = assign_server_address(s);
362 if (err != SRV_STATUS_OK)
363 return SN_ERR_INTERNAL;
364 }
365
366 if ((fd = s->srv_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
367 qfprintf(stderr, "Cannot get a server socket.\n");
368
369 if (errno == ENFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200370 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200371 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200372 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200373 else if (errno == EMFILE)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200374 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200375 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200376 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200377 else if (errno == ENOBUFS || errno == ENOMEM)
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200378 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200379 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200380 s->be->id, maxfd);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200381 /* this is a resource error */
382 return SN_ERR_RESOURCE;
383 }
384
385 if (fd >= global.maxsock) {
386 /* do not log anything there, it's a normal condition when this option
387 * is used to serialize connections to a server !
388 */
389 Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
390 close(fd);
391 return SN_ERR_PRXCOND; /* it is a configuration limit */
392 }
393
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100394#ifdef CONFIG_HAP_TCPSPLICE
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200395 if ((s->fe->options & s->be->options) & PR_O_TCPSPLICE) {
Willy Tarreau6d1a9882007-01-07 02:03:04 +0100396 /* TCP splicing supported by both FE and BE */
397 tcp_splice_initfd(s->cli_fd, fd);
398 }
399#endif
400
Willy Tarreaubaaee002006-06-26 02:48:02 +0200401 if ((fcntl(fd, F_SETFL, O_NONBLOCK)==-1) ||
402 (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1)) {
403 qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
404 close(fd);
405 return SN_ERR_INTERNAL;
406 }
407
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200408 if (s->be->options & PR_O_TCP_SRV_KA)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200409 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
410
411 /* allow specific binding :
412 * - server-specific at first
413 * - proxy-specific next
414 */
415 if (s->srv != NULL && s->srv->state & SRV_BIND_SRC) {
416 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
417 if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
418 Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200419 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200420 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200421 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200422 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200423 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200424 return SN_ERR_RESOURCE;
425 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100426#ifdef CONFIG_HAP_CTTPROXY
427 if (s->srv->state & SRV_TPROXY_MASK) {
428 struct in_tproxy itp1, itp2;
429 memset(&itp1, 0, sizeof(itp1));
430
431 itp1.op = TPROXY_ASSIGN;
432 switch (s->srv->state & SRV_TPROXY_MASK) {
433 case SRV_TPROXY_ADDR:
434 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
435 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
436 break;
437 case SRV_TPROXY_CLI:
438 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
439 /* fall through */
440 case SRV_TPROXY_CIP:
441 /* FIXME: what can we do if the client connects in IPv6 ? */
442 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
443 break;
444 }
445
446 /* set connect flag on socket */
447 itp2.op = TPROXY_FLAGS;
448 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
449
450 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
451 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
452 Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200453 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100454 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200455 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100456 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200457 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100458 return SN_ERR_RESOURCE;
459 }
460 }
461#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200462 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200463 else if (s->be->options & PR_O_BIND_SRC) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200464 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200465 if (bind(fd, (struct sockaddr *)&s->be->source_addr, sizeof(s->be->source_addr)) == -1) {
466 Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200467 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200468 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200469 "Cannot bind to source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200470 s->be->id, s->srv->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200471 return SN_ERR_RESOURCE;
472 }
Willy Tarreau77074d52006-11-12 23:57:19 +0100473#ifdef CONFIG_HAP_CTTPROXY
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200474 if (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100475 struct in_tproxy itp1, itp2;
476 memset(&itp1, 0, sizeof(itp1));
477
478 itp1.op = TPROXY_ASSIGN;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200479 switch (s->be->options & PR_O_TPXY_MASK) {
Willy Tarreau77074d52006-11-12 23:57:19 +0100480 case PR_O_TPXY_ADDR:
481 itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
482 itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
483 break;
484 case PR_O_TPXY_CLI:
485 itp1.v.addr.fport = ((struct sockaddr_in *)&s->cli_addr)->sin_port;
486 /* fall through */
487 case PR_O_TPXY_CIP:
488 /* FIXME: what can we do if the client connects in IPv6 ? */
489 itp1.v.addr.faddr = ((struct sockaddr_in *)&s->cli_addr)->sin_addr;
490 break;
491 }
492
493 /* set connect flag on socket */
494 itp2.op = TPROXY_FLAGS;
495 itp2.v.flags = ITP_CONNECT | ITP_ONCE;
496
497 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
498 setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
499 Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200500 s->be->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100501 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200502 send_log(s->be, LOG_EMERG,
Willy Tarreau77074d52006-11-12 23:57:19 +0100503 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200504 s->be->id, s->srv->id);
Willy Tarreau77074d52006-11-12 23:57:19 +0100505 return SN_ERR_RESOURCE;
506 }
507 }
508#endif
Willy Tarreaubaaee002006-06-26 02:48:02 +0200509 }
510
511 if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) &&
512 (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
513
514 if (errno == EAGAIN || errno == EADDRINUSE) {
515 char *msg;
516 if (errno == EAGAIN) /* no free ports left, try again later */
517 msg = "no free ports";
518 else
519 msg = "local address already in use";
520
521 qfprintf(stderr,"Cannot connect: %s.\n",msg);
522 close(fd);
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200523 send_log(s->be, LOG_EMERG,
Willy Tarreaubaaee002006-06-26 02:48:02 +0200524 "Connect() failed for server %s/%s: %s.\n",
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200525 s->be->id, s->srv->id, msg);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200526 return SN_ERR_RESOURCE;
527 } else if (errno == ETIMEDOUT) {
528 //qfprintf(stderr,"Connect(): ETIMEDOUT");
529 close(fd);
530 return SN_ERR_SRVTO;
531 } else {
532 // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
533 //qfprintf(stderr,"Connect(): %d", errno);
534 close(fd);
535 return SN_ERR_SRVCL;
536 }
537 }
538
539 fdtab[fd].owner = s->task;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200540 fdtab[fd].state = FD_STCONN; /* connection in progress */
Willy Tarreaud7971282006-07-29 18:36:34 +0200541 fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
Willy Tarreau54469402006-07-29 16:59:06 +0200542 fdtab[fd].cb[DIR_RD].b = s->rep;
Willy Tarreauf8306d52006-07-29 19:01:31 +0200543 fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
Willy Tarreau54469402006-07-29 16:59:06 +0200544 fdtab[fd].cb[DIR_WR].b = s->req;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200545
Willy Tarreauf161a342007-04-08 16:59:42 +0200546 EV_FD_SET(fd, DIR_WR); /* for connect status */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200547
548 fd_insert(fd);
549 if (s->srv) {
550 s->srv->cur_sess++;
551 if (s->srv->cur_sess > s->srv->cur_sess_max)
552 s->srv->cur_sess_max = s->srv->cur_sess;
553 }
554
Willy Tarreaua8b55e32007-05-13 16:08:19 +0200555 if (!tv_add_ifset(&s->req->cex, &now, &s->be->contimeout))
Willy Tarreaud7971282006-07-29 18:36:34 +0200556 tv_eternity(&s->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200557 return SN_ERR_NONE; /* connection is OK */
558}
559
560
561/*
562 * This function checks the retry count during the connect() job.
563 * It updates the session's srv_state and retries, so that the caller knows
564 * what it has to do. It uses the last connection error to set the log when
565 * it expires. It returns 1 when it has expired, and 0 otherwise.
566 */
567int srv_count_retry_down(struct session *t, int conn_err)
568{
569 /* we are in front of a retryable error */
570 t->conn_retries--;
571 if (t->conn_retries < 0) {
572 /* if not retryable anymore, let's abort */
Willy Tarreaud7971282006-07-29 18:36:34 +0200573 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200574 srv_close_with_err(t, conn_err, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100575 503, error_message(t, HTTP_ERR_503));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200576 if (t->srv)
577 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200578 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200579
580 /* We used to have a free connection slot. Since we'll never use it,
581 * we have to inform the server that it may be used by another session.
582 */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200583 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200584 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200585 return 1;
586 }
587 return 0;
588}
589
590
591/*
592 * This function performs the retryable part of the connect() job.
593 * It updates the session's srv_state and retries, so that the caller knows
594 * what it has to do. It returns 1 when it breaks out of the loop, or 0 if
595 * it needs to redispatch.
596 */
597int srv_retryable_connect(struct session *t)
598{
599 int conn_err;
600
601 /* This loop ensures that we stop before the last retry in case of a
602 * redispatchable server.
603 */
604 do {
605 /* initiate a connection to the server */
606 conn_err = connect_server(t);
607 switch (conn_err) {
608
609 case SN_ERR_NONE:
610 //fprintf(stderr,"0: c=%d, s=%d\n", c, s);
611 t->srv_state = SV_STCONN;
612 return 1;
613
614 case SN_ERR_INTERNAL:
Willy Tarreaud7971282006-07-29 18:36:34 +0200615 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200616 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100617 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200618 if (t->srv)
619 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200620 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200621 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200622 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200623 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200624 return 1;
625 }
626 /* ensure that we have enough retries left */
627 if (srv_count_retry_down(t, conn_err)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200628 return 1;
629 }
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200630 } while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200631
632 /* We're on our last chance, and the REDISP option was specified.
633 * We will ignore cookie and force to balance or use the dispatcher.
634 */
635 /* let's try to offer this slot to anybody */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200636 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200637 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200638
639 if (t->srv)
640 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200641 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200642
643 t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
644 t->srv = NULL; /* it's left to the dispatcher to choose a server */
Willy Tarreau3d300592007-03-18 18:34:41 +0100645 http_flush_cookie_flags(&t->txn);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200646 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 Tarreaue2e27a52007-04-01 00:01:37 +0200677 t->be->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 Tarreaua8b55e32007-05-13 16:08:19 +0200683 if (!tv_add_ifset(&t->req->cex, &now, &t->be->contimeout))
Willy Tarreaud7971282006-07-29 18:36:34 +0200684 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200685 t->srv_state = SV_STIDLE;
686 /* do nothing else and do not wake any other session up */
687 return 1;
688
689 case SRV_STATUS_FULL:
690 case SRV_STATUS_INTERNAL:
691 default:
Willy Tarreaud7971282006-07-29 18:36:34 +0200692 tv_eternity(&t->req->cex);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200693 srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
Willy Tarreau80587432006-12-24 17:47:20 +0100694 500, error_message(t, HTTP_ERR_500));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200695 if (t->srv)
696 t->srv->failed_conns++;
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200697 t->be->failed_conns++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200698
699 /* release other sessions waiting for this server */
Willy Tarreaue2e27a52007-04-01 00:01:37 +0200700 if (may_dequeue_tasks(t->srv, t->be))
Willy Tarreau96bcfd72007-04-29 10:41:56 +0200701 task_wakeup(t->srv->queue_mgt);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200702 return 1;
703 }
704 /* if we get here, it's because we got SRV_STATUS_OK, which also
705 * means that the connection has not been queued.
706 */
707 return 0;
708}
709
710
711/*
712 * Local variables:
713 * c-indent-level: 8
714 * c-basic-offset: 8
715 * End:
716 */